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

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

问题描述

序言



我正在开发几个网络服务和一些客户端(网络应用,移动设备等)通过HTTP(s)的所述服务。我目前的工作项目是为产品设计认证和授权解决方案。我已经决定利用Facebook,Google,微软,Twitter等外部身份提供商进行认证。



我正在努力解决问题, 当一个请求来到我的服务器,我怎么知道用户是谁,我如何确定?以下更多问题...



要求





  1. 系统应该使用基于令牌的身份验证(如相对于Cookie或基本认证)。



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



工作流程



根据我的阅读和理解基于令牌的身份验证,以下是我如何想象工作流。现在让我们专注于网页浏览器中的 Facebook 。我的假设是,其他外部身份提供者应该具有类似的功能,尽管我还没有确认。



请注意,在撰写本文时,我将以下内容从Facebook登录版本2.2


  1. 客户端:使用建议在Facebook用户令牌的第一次验证完成后创建自定义访问令牌。然后将自定义令牌发送给客户端以用于后续请求。但是,我想知道这是否比以上解决方案更复杂。这将需要实现我自己的身份提供者(我想避免的一些东西,因为我首先要使用外部身份提供者)。这个建议有什么好处吗?



  2. 在步骤3中的响应中是否有signedRequest字段以上(:





    当然,为了在服务器端进行比较,签名请求部分需要与请求一起发送到服务器(上述步骤#5)。除了可靠性而不牺牲安全性,我想知道性能如何与出站呼叫进行比较。


  3. 当我在,在什么方案/为什么目的,你会持续一个用户的访问令牌到数据库吗?
    我没有看到我需要这样做的场景,但是我可能会忽略某些东西。我很好奇,一些常见的情况可能是引发一些想法。


谢谢!

解决方案

根据您的描述,我建议使用如



中所述的服务器端登录流程

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



步骤(1)记录

中的人

你需要在范围参数中指定要从用户收集的权限。该请求只能通过正常链接触发:

  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}





(3)检查访问令牌



您可以通过

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

这只应该在服务器端完成,否则你会让你的应用访问令牌对最终用户可见(不是一个好主意!)。



请参阅





(4)扩展访问令牌



一旦获得(短命令)令牌,您可以执行按照





如下:

  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建议这样做:





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



作为FB如果令牌已过期(如果您未保存到期日期并在进行呼叫之前将其与当前时间戳进行比较),则不通知您),如果令牌无效,则可能会从FB接收到错误消息(之后)最大。 60天)。错误代码将为 190

  {
错误:{
message:验证访问令牌时出错:会话已过期在unix
时间SOME_TIME。当前unix时间为SOME_TIME。,
type:OAuthException ,
code:190
}
}






如果访问令牌变得无效,解决方案是让用户重新登录,此时您将能够再次进行API调用。您的应用程序用于新用户的登录流程应确定您需要采用哪种方法。



Preface

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...

Requirements

  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.

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.

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

  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)

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.)

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).

Questions

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

  2. 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.

    For instance, possible thoughts:

    • 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?

    • 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. 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?

    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.

  4. 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?

    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:

    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.

  5. 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.

Thanks!

解决方案

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

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).

The steps would be:

(1) Logging people in

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}

See

(2) Confirm the identitity

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

(3) Inspect the access token

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!).

See

(4) Extending the access token

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

like the following:

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

(5) Storing of access tokens

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

(6) Handling expired access tokens

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
  }
}

See

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天全站免登陆