Facebook OAuth 2.0“代码”和“令牌”

时间:2011-12-29 09:58:20

标签: facebook oauth-2.0 facebook-authentication

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

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

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

我想我误解了关于OAuth如何工作的基本信息,但是如果你第一次使用对话框获得令牌,那么你似乎完全避免了对code,token的请求。

11 个答案:

答案 0 :(得分:38)

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

您作为用户想要尝试一款名为Highjack的新Facebook应用。 所以你点击应用程序和Highjack应用程序。要求您登录您的Facebook帐户。完成后,Facebook会为您生成身份验证代码。

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

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

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

由于我们有2个派对(You和Highjack)通过Facebook进行身份验证,因此我们有2倍的机制。

答案 1 :(得分:27)

Salesforce Documentation无耻地借来:

授权码

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

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

答案 2 :(得分:21)

来自OAuth 2.0 Spec

  

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

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

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

答案 3 :(得分:7)

如果你看flow of 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服务器“我想授权此cliet(client_id)访问我的资源。这是我的身份验证(user_session_id或其他什么)”

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

您会看到,如果我们省略第2步,则无法保证客户端身份验证。任何客户端都可以使用不同的client_id调用step1,并获取该client_id的访问令牌而不是其自己的访问令牌。这就是为什么我们需要step2。

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

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

我们在Open Api平台中使用这种方法,但我们还没有发现任何安全问题。

顺便说一句,实际存在Implicit Grant type,即:

<client_id, redirect_uri> => access_token, refresh_token

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

答案 4 :(得分:5)

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

以下是IETF-oauth(http://tools.ietf.org/html/draft-ietf-oauth-v2-threatmodel-08#section-3.4)的原始配方:

3.4。授权码

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

  1. 基于浏览器的流程将协议参数暴露给潜在的    攻击者通过URI查询参数(HTTP referrer),浏览器    缓存或日志文件条目,可以重播。为了    减少此威胁,传递短期授权码    而不是令牌和更安全的交换令牌    客户端和授权服务器之间的直接连接。

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

答案 5 :(得分:3)

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

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

这似乎与选择隐式与授权代码授权流程的问题类似。 In fact, here is what looks like an opposite view point?!

另外,作为Drew mentioned

  

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

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

如果我是正确的,code%20token是一种优化,允许用户代理拥有令牌并允许服务器在单个请求中启动令牌交换过程(因为任何通过网络IO的内容都被认为是昂贵,特别是对用户代理而言。)

答案 6 :(得分:2)

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

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

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

有关更多信息,请观看此精彩视频:

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

答案 7 :(得分:2)

理论上,

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

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

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

enter image description here

答案 8 :(得分:1)

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

答案 9 :(得分:1)

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

第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

第2步。通过将授权代码作为POST请求发送来获取“访问令牌”

    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步。使用从上一步获得的访问令牌并检索用户资源

答案 10 :(得分:-1)

您在用户登录时收到令牌。但您可能希望在执行其他操作时更改令牌。 EG作为您的应用/页面发布或以offline_access用户身份发布。