应该如何Facebook的用户访问令牌可以在服务器端的消耗? [英] How should a Facebook user access token be consumed on the server-side?

查看:299
本文介绍了应该如何Facebook的用户访问令牌可以在服务器端的消耗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发多个Web服务和客户端的少数(Web应用程序,手机等)将与上述服务通过HTTP(S)接口。我现在的工作项目是设计的产品的认证和授权解决方案。我决定利用外部身份提供商,如Facebook,谷歌,微软,微博等进行验证。

I'm developing several web services and a handful of clients (web app, mobile, etc.) which will interface with said services over HTTP(s). My current work item is to design an authentication and authorization solution for the product. I have decided to leverage external identity providers, such as Facebook, Google, Microsoft, Twitter, and the like for authentication.

我试图解决的问题,当一个请求进入到我的服务器,我怎么知道用户是谁,我怎么能确定吗?。下面还有更多的问题...

I'm trying to solve the problem of, "when a request comes to my server, how do I know who the user is and how can I be sure?". More questions below as well...


  1. 依赖于外部身份,表明谁我处理('用户id'本质上是我所关心的)。

  2. 该系统应使用基于令牌的身份验证(而不是饼干,例如或基本身份验证)。

  1. Rely on external identities to indicate who I'm dealing with ('userId' essentially is all I care about).
  2. The system should use token based authentication (as opposed to cookies for example or basic auth).

我相信这是在多个客户端和服务器的扩展,同时提供松耦合的正确选择。

I believe this is the right choice for scaling across multiple clients and servers while providing loose coupling.

根据我的阅读和基于令牌认证的认识,下面是我想象中的工作流中。让我们关注目前在 Facebook在Web浏览器中。我的假设是,其他外部标识提供者应该有类似的功能,虽然我还没有证实,只是还没有。

Workflow

Based on my reading and understanding of token based authentication, the following is how I imagine the workflow to be. Let's focus for now on Facebook in a web browser. My assumption is that other external identity providers should have similar capabilities, though I have not confirmed just yet.

请注意,写作的,我立足下面掉的Facebook登录版本2.2

Note, as of writing, I'm basing the following off of Facebook login version 2.2


  1. 客户:使用的的JavaScript SDK

  2. Facebook的:用户认证和批准的应用权限(为例如接入用户的公开资料)

  3. Facebook的:将响应客户,其中包含用户的访问令牌,ID和签名的请求

  4. 客户:存储用户访问浏览器会话令牌(的由SDK处理方便

  5. 客户:由授权头+用户的ID沿用户的访问令牌发送(在自定义标题可能)向一个安全的资源我的web服务的请求

  6. 服务器:从请求头中读取用户的访问令牌,并通过向被Facebook所提供的debug_token图形API的请求启动验证

  7. Facebook的:回应返回与用户访问令牌信息服务器(包含APPID和用户id)

  8. 服务器:通过比较APPID什么是预期的(众所周知的本身)和用户id到什么是对客户端的请求发送
  9. 完成令牌验证
  10. 服务器:响应客户端请求与资源(假设快乐的授权路径)

  1. Client: Initiates login for Facebook using the JavaScript SDK
  2. Facebook: User authenticates and approves app permissions (to access user's public profile for example)
  3. Facebook: Sends response to client which contains user’s access token, ID, and signed request
  4. Client: Stores user access token in browser session (handled by SDK conveniently)
  5. Client: Makes a request to my web service for a secure resource by sending along the user’s access token in the authorization header + the user’s ID (in custom header potentially)
  6. Server: Reads user access token from request header and initiates verification by sending a request to the debug_token graph API provided by Facebook
  7. Facebook: Responds back to the server with the user access token info (contains appId and userId)
  8. Server: Completes verification of the token by comparing the appId to what is expected (known to itself) and the userId to what was sent on the client request
  9. Server: Responds to client with requested resource (assuming the happy authorization path)

我想象步骤5-9将重复后续请求到服务器(而用户的访问令牌是有效的 - 没有过期,从侧面FB撤销,应用权限更改等)

I’m imagining steps 5-9 would be repeated for subsequent requests to the server (while the user’s access token is valid – not expired, revoked from FB side, app permissions changed, etc.)

下面是一个图,以帮助的步骤走。请理解这个系统的不可以单页应用(SPA)。提到的Web服务是服务JSON数据返回到客户基本API端点;他们没有提供HTML / JS / CSS(与Web客户端的服务器除外)。

Here's a diagram to help go along with the steps. Please understand this system is not a single page application (SPA). The web services mentioned are API endpoints serving JSON data back to clients essentially; they are not serving HTML/JS/CSS (with the exception of the web client servers).


  1. 首先,是否有任何明显的差距/坑瀑布与所描述的方法基于我的preface和要求?

  1. First and foremost, are there any glaring gaps / pit falls with the described approach based on my preface and requirements?

是验证访问令牌进行Facebook的出站请求,每个客户端请求(上述步骤6-8) 要求/建议?

Is performing an outbound request to Facebook for verifying the access token (steps 6-8 above) per client request required / recommended?

我知道最起码,我必须验证来自客户端的请求来访问令牌。但是,对于第一次后,后续的验证推荐的方法是未知的我。如果有典型模式,我有兴趣听到他们。我知道他们可能是基于我的要求取决于应用程序;不过,我只是不知道要寻找什么呢。我会在尽职调查,一旦我有一个基本的想法。

I know in the very least, I must verify the access token coming from client request. However, the recommended approach for subsequent verifications after the first is unknown to me. If there are typical patterns, I’m interested in hearing about them. I understand they may be application dependent based on my requirements; however, I just don’t know what to look for yet. I’ll put in the due diligence once I have a basic idea.

例如,可能的想法:


  • 哈希访问令牌+用户id对后的第一次验证完成并将其存储在一个分布式缓存(由所有Web服务器访问),与到期等于访问令牌的。一旦从客户的后续请求,哈希访问令牌+用户id对,检查它是否存在于缓存中。如果present,则请求被授权。否则,接触到Facebook的图形API,以确认访问令牌。我假设,如果我使用HTTPS(我会)这一战略可能是可行的。但是,如何表现比较?

  • Hash the access token + userId pair after first verification is complete and store it in a distributed cache (accessible by all web servers) with expiry equal to access token’s. Upon subsequent requests from the clients, hash the access token + userId pair and check its existence in the cache. If present, then request is authorized. Otherwise, reach out to Facebook graph API to confirm the access token. I’m assuming this strategy might be feasible if I’m using HTTPS (which I will be). However, how does performance compare?

在<一个接受的答案href=\"http://stackoverflow.com/questions/12065492/rest-api-for-website-which-uses-facebook-for-authentication\">this 建议Facebook的用户令牌的第一核实后创建一个自定义的访问令牌的StackOverflow问题是完整的。然后将自定义的令牌将被发送到客户端后续请求。我想知道如果这比上面的解决方案更为复杂,但是。这就需要实现我自己的身份提供程序(这是我想避免,因为我想首先使用外部标识提供者...)。是否有任何好处这一建议?

The accepted answer in this StackOverflow question recommends creating a custom access token after the first verification of the Facebook user token is complete. The custom token would then be sent to the client for subsequent requests. I’m wondering if this is more complex than the above solution, however. This would require implementing my own Identity Provider (something I want to avoid because I want to use external identity providers in the first place…). Is there any merit to this suggestion?

是在上面的步骤#3的响应signedRequest场present(自提<一个href=\"https://developers.facebook.com/docs/facebook-login/login-flow-for-web/v2.2#checklogin\">here),相当于签名的请求参数<一个href=\"https://developers.facebook.com/docs/facebook-login/using-login-with-games#checklogin\">here在游戏画布上登录流量?

Is the signedRequest field present on the response in step #3 above (mentioned here), equivalent to the signed request parameter here in the ‘games canvas login’ flow?

他们似乎暗示为因为文档中的链接前向后者等价的。不过,我很惊讶游戏页面上提到的验证策略是不是在手动构建一个登录流程<一提到href=\"https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow#confirm\">page的Web文档。

They seem to be hinted as equivalent since the former links to the latter in the documentation. However, I’m surprised the verification strategy mentioned on the games page isn’t mentioned in the ‘manually building a login flow’ page of the web documentation.

如果答案#3是,可解码所述签名,并比较所预期在服务器侧使用的相同的身份确认策略?

If the answer to #3 is ‘Yes’, can the same identity confirmation strategy of decoding the signature and comparing to what is expected be used on the server-side?

建议我不知道这是否可以代替杠杆使得到debug_token图形API的呼出(步骤#6以上),以确认访问令牌的<一个href=\"https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/v2.2#checktoken\">here:

I’m wondering if this can be leveraged instead of making an outbound call to the debug_token graph API (step #6 above) to confirm the access token as recommended here:

当然,为了使在服务器侧的相比,签名的请求部将需要与请求给服务器(步骤#5的上方)一起发送。除了可行性不牺牲安全性,我不知道如何表现会比较使呼出。

Of course, in order to make the comparison on the server-side, the signed request portion would need to be sent along with the request to the server (step #5 above). In addition to feasibility without sacrificing security, I’m wondering how the performance would compare to making the outbound call.

而我在这,在什么情况下/目的是什么,你会坚持用户的访问令牌例如数据库?
我没有看到这样一个场景,我需要做到这一点,但是,我可能会忽视的东西。我很好奇,是一些常见的场景可能会引发一些想法。

While I’m at it, in what scenario / for what purpose, would you persist a user's access token to a database for example? I don’t see a scenario where I would need to do this, however, I may be overlooking something. I’m curious was some common scenarios might be to spark some thoughts.

谢谢!

推荐答案

从你的描述我会建议使用服务器端登录流程为

From what you describe I'd suggest to use a server-side login flow as described in

  • https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/v2.2

,使得令牌是已经在服务器上,并且不需要从客户端传递。如果您在使用非加密的连接,这可能是一个安全风险(例如,对于人在这方面的中间人攻击)。

so that the token is already on your server, and doesn't need to be passed from the client. If you're using non-encrypted connections, this could be a security risk (e.g. for man-in-the-middle attacks).

的步骤将是:

(1)伐木人

您需要指定您希望从范围参数的用户聚集的权限。该请求可以通过只是一个正常的链接触发:

You need to specify the permission you want to gather from the users in the scope parameter. The request can be triggered just via a normal link:

GET https://www.facebook.com/dialog/oauth?
    client_id={app-id}
   &redirect_uri={redirect-uri}
   &response_type=code
   &scope={permission_list}

请参阅

(2)确认身份的定位

GET https://graph.facebook.com/oauth/access_token?
    client_id={app-id}
   &redirect_uri={redirect-uri}
   &client_secret={app-secret}
   &code={code-parameter}


  • https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/v2.2#confirm

  • (3)检查访问令牌

    您可以检查令牌因为你已经在你的问题通过

    You can inspect the token as you already said in your question via

    GET /debug_token?input_token={token-to-inspect}
        &access_token={app-token-or-admin-token}
    

    这只能做服务器端,否则你就会让你的应用程序访问令牌可见的最终用户(不是一个好主意!)。

    This should only be done server-side, because otherwise you'd make you app access token visible to end users (not a good idea!).

    请参阅

    (4)扩展的访问令牌

    一旦你得到了(短期)的道理,你可以做一个呼吁延长令牌作为

    Once you got the (short-lived) token, you can do a call to extend the token as described in

    • https://developers.facebook.com/docs/facebook-login/access-tokens#extending

    这样的:

    GET /oauth/access_token?grant_type=fb_exchange_token
        &client_id={app-id}
        &client_secret={app-secret}
        &fb_exchange_token={short-lived-token}
    

    (5)的访问令牌的存储

    关于在服务器上的标记的存储,FB建议这样做:

    Concerning the storing of the tokens on the server, FB suggests to do so:

    (6)处理过期的访问令牌

    由于FB不通知你,如果令牌已过期(如果你不保存失效日期,并拨打电话之前比较这对当前的时间戳),它可能是你从FB收到错误消息,如果令牌得到无效(最大后60天)。错误code将 190

    As FB doesn't notify you if a token has expired (and if you don't save the expiry date and compare this to the current timestamp before making a call), it's possible that you receive error messages from FB if the token got invalid (after max. 60 days). The error code will be 190:

    {
      "error": {
        "message": "Error validating access token: Session has expired at unix 
                    time SOME_TIME. The current unix time is SOME_TIME.", 
        "type": "OAuthException", 
        "code": 190
      }
    }
    

    请参阅

    如果访问令牌失效后,解决方案是让用户再次登录,此时您将能够代表他们的API调用一次。登录流程应用程序使用,为新人们应该确定需要采用哪种方法。

    If the access token becomes invalid, the solution is to have the person log in again, at which point you will be able to make API calls on their behalf once more. The login flow your app uses for new people should determine which method you need to adopt.

    这篇关于应该如何Facebook的用户访问令牌可以在服务器端的消耗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆