用于网站的REST API,使用Facebook进行身份验证

Ada*_*dam 84 openid authentication rest facebook facebook-authentication

我们有一个网站,登录和验证自己的网站的唯一方法是使用Facebook(这不是我的选择).第一次使用Facebook登录时,会自动为您创建一个帐户.

我们现在想为我们的网站创建一个iPhone应用程序,也为其他人创建一个公共API来使用我们的服务.

这个问题是关于如何通过app/API对我们的网站进行身份验证,并分为两部分:

  1. 从API到仅使用Facebook OAuth作为身份验证方法的网站处理REST身份验证的正确方法是什么?

    我已经阅读并研究了很多关于REST API的标准身份验证方法.我们不能通过HTTPS使用Basic Auth等方法,因为没有用户凭证.像这样的东西似乎只是用于使用API​​验证应用程序.

    目前,我认为最好的方法是在API上点击/授权终点,重定向到Facebook OAuth,然后重定向回站点并提供API的用户可以用来验证后续的"令牌"要求.

  2. 对于我们创建的官方应用程序,我们不一定需要以相同的方式使用公共API.那么与我们的网站交流并对用户进行身份验证的最佳方式是什么?

我理解(我认为)如何使用API​​(公共)密钥和秘密(私有)密钥验证使用我们的API的第三方应用程序.但是,当涉及到对正在使用该应用程序的用户进行身份验证时,我对如何进行此操作感到困惑,因为我们必须对用户进行身份验证的唯一方法是Facebook.

我觉得我错过了一些非常明显的东西,或者没有完全理解公共REST API应该如何工作,所以任何建议和帮助将不胜感激.

小智 93

更新:见下文

我也一直在思考这个问题.我还不完全清楚,但这是我想要走的路线.我正在创建一个REST API,我的用户只能使用Facebook连接进行身份验证.

在客户端:

  1. 使用Facebook API登录并获取OAUTH2代码.
  2. 将此代码交换为访问令牌.
  3. 在每次调用我的自定义API时,我都会包含Facebook用户ID和访问令牌.

在API上(对于需要用户身份验证的每个方法):

  1. 使用上面的访问令牌向/我Facebook图表发出请求.
  2. 验证返回的Facebook用户ID是否与从上面传递给我的API的用户ID相匹配.
  3. 如果访问令牌已过期,则需要额外的通信.

我还没有测试过这个.听起来怎么样?

---更新:2014年7月27日回答问题---

登录时我只使用上述交换一次.一旦我确定登录了哪个用户,我就创建了自己的访问令牌,并且从那一点开始使用该令牌.所以新流程看起来像这样......

在客户端:

  1. 使用Facebook API登录并获取OAUTH2代码.
  2. 将此代码交换为访问令牌.
  3. 我的 API 请求访问令牌,包括Facebook令牌作为参数

在API上

  1. 接收访问令牌请求.
  2. 使用facebook访问令牌向/我Facebook图表发出请求
  3. 验证Facebook用户是否存在并与我的数据库中的用户匹配
  4. 创建我自己的访问令牌,保存它并将其返回到客户端以便从此时开始使用


All*_*ітy 14

这是我使用JWT(JSON Web令牌)的实现,基本上类似于Chris的更新答案.我使用过Facebook JS SDK和JWT.

这是我的实施.

  1. 客户端:使用Facebook JS SDK登录并获取访问令牌.

  2. 客户端:通过调用/verify-access-token端点从我的API请求JWT .

  3. MyAPI:接收访问令牌,通过调用/meFacebook API的端点进行验证.

  4. MyAPI:如果访问令牌有效,则从数据库中查找用户,如果存在,则登录用户.创建一个JWT,其中包含必填字段作为有效负载,设置到期日期,使用密钥签名并发送回客户端.

  5. 客户端:将JWT存储在本地存储中.

  6. 客户端:发送令牌(步骤5中的JWT)以及下一次API调用的请求.

  7. MyAPI:使用密钥验证令牌,如果令牌有效,则将令牌换成新令牌,将其与API响应一起发送回客户端.(之后没有外部API调用以验证令牌)[如果令牌无效/过期请求客户端再次进行身份验证并从1开始重复]

  8. 客户端用新的令牌替换存储的令牌,并将其用于下一次API调用.一旦满足令牌到期,令牌就会过期撤销对API的访问.

每个令牌都使用一次.

阅读有关安全性和JWT的更多答案

JWT的安全性如何

如果你能解码JWT它们如何安全?

JSON Web Tokens(JWT)作为用户标识和身份验证令牌

  • 我想#3应该是[`/debug_token`](https://developers.facebook.com/docs/graph-api/reference/v2.7/debug_token),所以你可以检查一下这个令牌是否适合你应用. (2认同)
  • 不要在客户端请求`access_token`.使用"代码工作流程".将`code`传递给MyAPI并再次往返Facebook,用`access_token`交换`code`.这里有更详细的解释:https://developers.facebook.com/docs/facebook-login/security (2认同)

Oli*_*nce 5

我想回答同样的问题,并且最近经历了很多阅读......

我不会有"答案",但事情对我来说有点清楚.您是否阅读过您提到的文章中的评论?我发现它们非常有趣且有用.

因此,根据自第一篇文章撰写以来事物的演变情况,以下是我认为我会做的事情:

  • 无处不在的HTTPS - 这让你忘记了HMAC,签名,nonce,......

  • 使用OAuth2:

    • 当身份验证请求来自我自己的应用程序/网站时,请使用前面提到的文章回复中描述的"技巧"(或其变体).

    • 就我而言,我有两种类型的用户:具有经典登录/密码凭据的用户和已注册Facebook Connect的用户.
      因此,我将提供一个"登录Facebook"按钮的常规登录表单.如果用户使用"经典"凭据登录,我只需将其发送到我的OAuth2端点即可grant_type=password.
      如果他选择通过Facebook登录,我认为这将是一个两步骤的过程:

      • 首先,使用Facebook iOS SDK打开FBSession
      • 当这样做并且应用程序被给予后退控制时,应该有一种方法来获得该用户的Facebook ID.我将此ID单独发送到我的OAuth2端点,扩展授权由我的服务器理解为"使用FB用户ID".

请注意,我仍然在研究所有这些东西,所以这可能不是一个完美的答案......也许甚至不是一个正确的答案!但我认为这将是一个很好的起点.使用"扩展授权"进行Facebook身份验证的想法可能需要注册才能正确执行操作?我不太确定.

无论如何,我希望我能够帮助你甚至一点,至少它可以开始讨论找到这个问题的最佳解决方案:)

更新
Facebook登录不是评论中指出的解决方案:任何人都可以发送任意用户ID并以API上的此用户身份登录.

怎么样这样做:

  • 显示带有"Facebook登录"按钮的登录表单
  • 如果选择此登录方法,请像Facebook SDK一样:从您的身份验证服务器打开一个网页,这将启动Facebook登录.
  • 一旦用户登录,Facebook将使用您的重定向URL进行确认; 使该URL指向您的身份验证服务器的另一个端点(可能带有一个额外的参数,表明该呼叫来自某个应用程序?)
  • 当命中认证端点时,认证可以安全地识别用户,保留其FB用户ID/FB会话并使用自定义URL方案向您的应用返回访问令牌,就像Facebook SDK会做的那样

看起来更好?