71

为什么您需要 Facebook OAuth2 身份验证流程中的“代码”和“令牌”,如下所述:https ://developers.facebook.com/docs/authentication/ ?

如果您查看 OAuth 对话框参考(https://developers.facebook.com/docs/reference/dialogs/oauth/),您似乎只使用令牌来获取有关用户的信息,并且如果您指定response_type参数为tokenor code,token,则您第一次获得令牌。

为什么需要获取“代码”,然后使用代码获取“令牌”而不是直接获取令牌?

https://graph.facebook.com/oauth/access_token我想我对 OAuth 的工作原理有一些基本的误解,但是如果您第一次通过对话框获得令牌,您似乎完全避免了请求。

4

11 回答 11

55

让我们举一个简单的例子来区分身份验证代码和访问令牌。

作为用户,您想尝试一个名为 Highjack 的新 Facebook 应用程序。因此,您单击该应用程序,Highjack 应用程序会要求您登录您的 Facebook 帐户。完成后,Facebook 会为您生成一个验证码。

然后将此代码传递给使用其自己的 FB 客户端 ID、FB 密码和您的身份验证代码的 Highjack 服务器来获取访问令牌。

在上面的示例中,身份验证代码确认您作为用户是有效的 FB 用户。但是第二步说“作为 FB 用户,您正在授予对某些资源的 Highjack 应用程序的访问权限”。

如果 Highjack 应用程序需要隐式授权(即直接访问令牌),那么您也可以看到访问令牌,因为它正在与浏览器进行交换。这意味着您现在可以使用访问令牌代表 Highjack 调用所有 Facebook API。(您只能使用访问令牌来获取您的个人信息,但 Facebook 无法知道谁在调用他们的 API。)

由于我们有 2 方(您和 Highjack)使用 Facebook 进行身份验证,因此我们有这种 2 折机制。

于 2016-04-27T00:57:51.850 回答
30

从Salesforce 文档中无耻地借用:

授权码

授权代码是代表用户访问权限的短期令牌,由授权服务器创建并通过浏览器传递给客户端应用程序。客户端应用程序将授权代码发送到授权服务器以获取访问令牌和可选的刷新令牌。

访问令牌 客户端使用访问令牌代表最终用户发出经过身份验证的请求。它的生命周期比授权代码长,通常为几分钟或几小时。当访问令牌过期时,尝试使用它会失败,并且必须通过刷新令牌获取新的访问令牌。

于 2012-06-01T19:45:34.437 回答
23

来自OAuth 2.0 规范

授权代码提供了一些重要的安全优势,例如验证客户端的能力,以及将访问令牌直接传输到客户端而不通过资源所有者的用户代理传递它,从而可能将其暴露给其他人,包括资源所有者.

所以,基本上 - 主要原因是限制获得访问令牌的参与者的数量。

“令牌”响应主要用于浏览器中的客户端(例如:JavaScript 客户端)。

于 2011-12-29T18:12:19.747 回答
10

如果你看Authorization Code OAuth type 的流程,是的,有两个精算步骤:

  1. <user_session_id, client_id> => authorization_code
  2. <client_id, redirect_uri, authorization_code, client_secret> => access_token, refresh_token

在第 1 步中:用户告诉 OAuth 服务器“我想验证此客户端 ( client_id) 以访问我的资源。这是我的验证 (user_session_id或其他)”

在第 2 步:客户端 ( client_id) 告诉 OAuth 服务器“我已获得用户授权 ( authorization_code),请给我一个访问令牌以供以后访问。这是我的身份验证 ( client_id& client_secret)”

你看,如果我们省略第 2 步,则无法保证客户端身份验证。任何客户端都可以使用不同的方法调用 step1client_id并获得一个访问令牌,client_id而不是自己的。这就是为什么我们需要第二步。

如果你真的想结合 step1 和 step2,你可以这样做:

<client_id, redirect_uri, client_secret> => access_token, refresh_token

我们在我们的开放 API 平台中使用了这种方法,我们还没有发现任何安全问题。

顺便说一句,实际上有一个隐式授予类型,即:

<client_id, redirect_uri> => access_token, refresh_token

它通常适用于没有服务器后端的仅客户端应用程序。在这种情况下,OAuth 服务器必须确保重定向 URI 属于该客户端(redirect_uri例如,与 register 相同)。

于 2016-05-23T07:39:15.340 回答
9

答案)您需要/想要代码和令牌以获得额外的安全性。

根据 Nate Barbettini 的说法,我们需要额外的步骤来交换访问令牌的身份验证码,因为身份验证码可以在前端通道中使用(不太安全),而访问令牌可以在后端通道中使用(更安全) .

因此,安全优势在于访问令牌不会暴露给浏览器,因此无法从浏览器中拦截/获取。我们更信任网络服务器,它通过反向渠道进行通信。访问令牌是秘密的,然后可以保留在 Web 服务器上,并且不会暴露给浏览器(即前端通道)。

有关更多信息,请观看这​​个精彩的视频:

OAuth 2.0 和 OpenID Connect(简单英语) https://youtu.be/996OiexHze0?t=26m30s(开始 26 分钟)

于 2018-05-08T23:01:48.820 回答
9

混淆是因为用户代表他自己而不是客户端应用程序对授权服务器(即facebook)进行身份验证。保护客户端应用程序(使用 https)然后保护用户代理(浏览器)非常简单。

这是来自 IETF-oauth 的原始公式(https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-threatmodel-08#section-3.4):

3.4. 授权码

授权码代表成功的最终用户授权过程的中间结果,并被客户端用于获取访问和刷新令牌。授权码被发送到客户端的重定向 URI 而不是令牌有两个目的。

  1. 基于浏览器的流通过 URI 查询参数(HTTP 引荐来源网址)、浏览器缓存或日志文件条目向潜在攻击者公开协议参数,并且可以重放。为了减少这种威胁,使用短期授权代码而不是令牌,并通过客户端和授权服务器之间更安全的直接连接交换令牌。

  2. 在客户端和授权服务器之间的直接请求期间对客户端进行身份验证比在间接授权请求的上下文中简单得多。后者需要数字签名。

于 2015-12-02T10:23:02.383 回答
4

理论上,

  • 访问令牌无法告诉我们用户是否已通过身份验证,但身份验证代码可以。
  • 不应使用身份验证代码来获取对 API 的访问权限,但应该使用访问令牌。

如果您有一个单页应用程序或移动应用程序,没有后端或后端最少,您的应用程序可能希望直接在前端访问用户的 FB 数据。因此提供了访问令牌。

在另一种情况下,您可能希望用户使用 Facebook、Google 等外部身份验证服务提供商注册/登录您的应用程序。在这种情况下,您的前端会将身份验证代码发送到可用于获取访问令牌的后端来自服务器端的 Facebook。现在您的服务器可以从服务器访问用户的 FB 数据。

在此处输入图像描述

于 2018-10-16T08:22:42.543 回答
3

基本上,作为Lix 答案的扩展,访问代码路由允许资源所有者(即 Facebook 用户)撤销对其用户代理(即他们的浏览器)的授权,例如通过注销,而不撤销对离线客户端的授权(即你的申请)。如果这不重要,则无需使用访问代码路由。

此外,提供访问代码是为了确保提供给服务器的令牌实际注册到资源所有者(即 Facebook 用户),而不是用户代理(或中间人)。

这似乎类似于选择隐式与授权代码授予流程的问题。事实上,这看起来像是一个相反的观点?!.

此外,正如德鲁所说

当访问令牌过期时,尝试使用它会失败,并且必须通过刷新令牌获取新的访问令牌。

另一部分是刷新令牌,但我认为在 FB Docs 中没有很好地解释这一点。如果我是正确的,隐式授权(直接令牌)应该是非常短暂的,但这是要强制执行的,FB.js 似乎隐藏了很多(这个我没有深入研究) .

如果我是正确的,这code%20token是一种优化,允许用户代理拥有令牌并允许服务器在单个请求中启动令牌交换过程(因为网络 IO 上的任何东西都被认为是昂贵的,尤其是对于用户代理) .

于 2014-07-09T13:41:29.507 回答
2

这是因为使用只有 FB 和客户端知道的共享密钥将访问令牌提供给 AUTHENTICATED 客户端(第三方应用程序)。用户可以直接请求访问令牌的唯一方法是知道共享秘密,这将使秘密公开并可能导致中间人攻击。此外,虽然 FB 可以保证与用户的安全连接,但 FB 不能保证将令牌传递给客户端是安全的。但是,FB(和 OAuth2)确实需要客户端和 FB 之间的安全连接。访问令牌与客户端公共 ID(通常经过哈希处理)相关联,这意味着只有原始客户端应用程序才能使用它来请求令牌,因为密钥与授权代码一起发送以获取访问令牌。

于 2017-03-01T03:04:29.547 回答
2

在带有 facebook 的 OAuth 2.0 中,整体概念很简单,如下所示。

Step 1. 通过 GET 请求获取“授权码”

request URI: https://www.facebook.com/dialog/oauth
Params:
    response_type=code
    client_id={add your "App id" got by registering app}
    redirect_uri={add redirect uri defined at the registration of app}
    scope={add the scope needed in your app}
Headers: None

Step 2. 通过POST请求发送授权码获取“Access Token”

    URI: https://graph.facebook.com/oauth/access_token
    Params:
        grant_type=authorization_code
        client_id=<add your "App id" got by registering app>
        redirect_uri=<add redirect uri defined at the registration of app>
        code=<obtained authorization code from previous step>
    Headers:
        Authorization:Basic encode <App Id:App Secret> with base64 
        Content-Type:application/json

步骤 3. 使用从上述步骤获得的访问令牌并检索用户资源

于 2019-09-25T14:42:23.123 回答
-1

当用户登录时,您会收到一个令牌。但您可能希望在执行其他操作时更改该令牌。EG 作为您的应用程序/页面发布或作为用户发布offline_access

于 2011-12-29T10:07:24.903 回答