两个工作流程有什么区别?何时使用授权码流程?

div*_*shm 152 oauth oauth-2.0

OAuth 2.0具有多个工作流程.关于这两个,我有几个问题.

  1. 授权代码流 - 用户从客户端应用程序登录,授权服务器向应用程序返回授权代码.然后,应用程序交换访问令牌的授权码.
  2. 隐式授权流程 - 用户从客户端应用程序登录,授权服务器直接向客户端应用程序发出访问令牌.

这两种方法在安全性方面有什么区别?哪一个更安全,为什么?

当服务器可以直接发出Access令牌时,我没有看到为什么在一个工作流中添加额外步骤(令牌的交换授权代码)的原因.

不同的网站说,当客户端应用程序可以保证凭据安全时,使用授权代码流.为什么?

Eug*_*ace 192

access_token是你需要调用一个受保护的资源(一个API)是什么.在授权代码流程中,有两个步骤可以获得它:

  1. 用户必须进行身份验证并将codeAPI 返回给API使用者(称为"客户端").
  2. 该API的(通常是您的Web服务器)的"客户"交流code在#1的获得access_token,与认证本身client_idclient_secret
  3. 然后它可以用API调用API access_token.

因此,有一个双重检查:拥有通过API浮出资源的用户和使用API​​的客户端(例如Web应用程序).两者都经过验证可以获得授权.请注意OAuth的"授权"性质:用户授予对其资源的访问权限(通过code返回的身份验证后)到应用程序,应用程序获取access_token,并代表用户进行调用.

在隐式流程中,省略步骤2.因此,在用户身份验证之后,access_token会直接返回a,您可以使用它来访问资源.API不知道谁在调用该API.任何有access_token罐头的人,而在前面的例子中只有网络应用程序(它的内部通常不是任何人都可以访问).

隐式流通常用于存储client idclient secret不推荐的场景(例如,设备,尽管很多人都这样做).这就是免责声明的含义.人们可以访问客户端代码,因此可以获取凭据并假装成为资源客户端.在隐式流程中,所有数据都是易失性的,并且应用程序中没有任何内容存储.

  • Eugenio精彩解释!谢谢! (9认同)
  • @Madnik7G 原因与这个答案所解释的(漂亮)正交:可能涉及第三方。整个流程由用户代理(例如:浏览器)精心安排,但最终授权服务器(例如:“使用 Facebook 登录”)将直接与客户端(例如,您的服务器端 BFF)对话最终访问资源,因此用户代理永远不会直接访问。 (3认同)
  • 我知道原来的答案已经有 5 多年历史了,但这是我读过的最简单、最干净的解释。谢谢@EugenioPace (2认同)

Geo*_*ell 50

我将在这里添加一些我认为在上述答案中没有明确的内容:

  • 授权 - 代码流允许最终访问令牌永远不会到达,并且永远不会存储在具有浏览器/应用程序的计算机上.临时授权代码通过浏览器/ app提供给计算机,然后发送到服务器.然后,服务器可以使用完全访问令牌进行交换,并可以访问API等.具有浏览器的用户只能通过带有令牌的服务器访问API.
  • 隐式流只能涉及两方,最终访问令牌通过浏览器/应用程序存储在客户端上.如果此浏览器/应用程序遭到入侵,那么他们的身份验证令牌可能会很危险.

如果您不信任用户计算机来保存令牌但是您确实信任自己的服务器,那么tl; dr不使用隐式流.

  • re:*使用浏览器的用户只能通过带有令牌的服务器访问API.*但服务器需要向浏览器发送**内容,以便入站请求可以与持有的令牌相关联服务器端.如果你愿意,可以使用cookie.如果服务器没有将令牌传输到浏览器中运行的JS,它必须传输其他东西,(浏览器)客户端需要传递给服务器,以便允许服务器代表特定客户端行动. (11认同)

Bas*_*hdy 14

两者之间的区别在于:

  1. 在Implicit流中,令牌直接通过带有"#"符号的重定向URL返回,这主要用于javascript客户端或没有服务器端的移动应用程序,并且客户端不需要在某些实现中提供其秘密.

  2. 在授权代码流中,代码以"?"返回 如果服务器端可以读取,则服务器端必须在此时向令牌URL提供客户端密钥,以便从授权服务器获取令牌作为json对象.如果您有可以处理此问题的应用程序服务器并将用户令牌与他/她的配置文件存储在他自己的系统上,并且主要用于常见的移动应用程序,则使用它.

所以它取决于你的客户端应用程序的性质,一个更安全的"授权代码",因为它在客户端请求秘密,并且令牌可以在非常安全的连接上在授权服务器和客户端应用程序之间发送,授权提供者可以限制某些客户端仅使用"授权代码"并禁止隐式

  • 可以的!我可能忽略了这一点.基本上,授权代码流将由整个服务器是客户端的系统使用 - 浏览器发出请求并获取代码.代码被发送到安全连接到资源服务器的客户端服务器.我理解正确吗?访问令牌永远不会到达最终用户的机器? (2认同)

Lut*_*for 5

隐式授权与授权代码授权类似,但有两个不同之处。

它旨在用于无法保密客户端机密的基于用户代理的客户端(例如单页 Web 应用程序),因为所有应用程序代码和存储都可以轻松访问。

其次,不是授权服务器返回用于交换访问令牌的授权代码,而是授权服务器返回访问令牌。

请在此处找到详细信息 http://oauth2.thephpleague.com/authorization-server/which-grant/


Ali*_*ahi 5

哪个更安全,为什么?

它们都是安全的,这取决于您使用它的环境。

当服务器可以直接发出访问令牌时,我看不出为什么要在一个工作流程中添加额外步骤(令牌的交换授权代码)的原因。

很简单。您的客户端不安全。让我们详细看看它。

考虑您正在针对 开发应用程序Instagram API,因此您可以使用 APP 注册Instagram并定义API's您需要的应用程序。Instagram将为您提供client_idclient_secrect

在你的网站上,你设置了一个链接,上面写着。“来使用我的应用程序”。单击此按钮,您的 Web 应用程序应两次调用Instagram API.

FirstInstagram Authentication Server使用以下参数发送请求。

1. `response_type` with the value `code`
2. `client_id` you have get from `Instagram`
3. `redirect_uri` this is a url on your server which do the second call
4. `scope` a space delimited list of scopes
5. `state` with a CSRF token. 
Run Code Online (Sandbox Code Playgroud)

您不发送client_secret,您无法信任客户端(尝试使用您的应用程序的用户和/或他的浏览器)。客户端可以看到 url 或 java 脚本并client_secrect轻松找到您的。这就是您需要另一个步骤的原因。

您收到一个codestate。在code这里temporary并没有任何地方保存。

然后你second打电话给Instagram API(从你的服务器)

 1. `grant_type` with the value of `authorization_code`
 2. `client_id` with the client identifier
 3. `client_secret` with the client secret
 4. `redirect_uri` with the same redirect URI the user was redirect back to
 5. `code` which we have already received.
Run Code Online (Sandbox Code Playgroud)

由于调用是从我们的服务器发出的,我们可以安全地使用client_secret(显示我们是谁),code显示用户已授予client_id使用资源的权限。

作为回应,我们将有 access_token