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


86

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

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

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

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

    我已经阅读并研究了很多有关REST API身份验证的标准方法。我们不能使用基于HTTPS的基本身份验证之类的方法,因为这样的用户没有凭据。喜欢的东西,似乎是仅适用于使用API验证的应用程序。

    目前,我认为最好的方法是您点击我们API上的/ authorize端点,它重定向到Facebook OAuth,然后重定向回该站点并提供一个“令牌”,API的用户可以使用该令牌来认证后续要求。

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

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

我感觉好像缺少了很明显的东西,或者不完全了解公共REST API的工作方式,因此,我们将不胜感激任何建议和帮助。


我在stackoverflow.com/questions/30230482/…上也有类似的问题,其中讨论了其中一些
JVK 2015年

Answers:


99

更新:请参见下文

我也一直在努力思考这个问题。对我来说还不是很清楚,但这是我正在考虑的路线。我正在创建一个REST API,我的用户只能通过Facebook连接进行身份验证。

在客户端上:

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

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

  1. 使用上方的访问令牌向/ me Facebook图进行请求。
  2. 验证返回的Facebook用户ID是否与从上方传递给我的API的用户ID匹配。
  3. 如果访问令牌已过期,则需要进行其他通信。

我尚未对此进行测试。听起来如何?

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

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

在客户端上:

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

在API上

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

嘿,这是一个较晚的答复,但是您的解决方案似乎可以解决我在第一个答案中遇到的问题。当然,您必须使用HTTPS才能不以明文形式发送(id,token)对。但是看起来应该可以!
奥利维尔·兰斯

我认为最好在服务器上调用/ me并生成您自己的访问令牌,供移动客户端使用。
Der_Meister 2014年

我发现将FB机密存储在移动应用程序中是不好的做法。Facebook建议仅将其存储在您的服务器上。developers.facebook.com/docs/opengraph/using-actions/...
Der_Meister

如果我们每次都将user_id和access_token发送到API服务器(作为post / get参数)。如果有人能够拦截连接,是否会造成安全漏洞?
内森·

@NathanDo在客户端和API服务器之间使用HTTPS,如果有人拦截了连接,则应该没有问题(撇开了Heartbleed类型的漏洞)。
dcr

15

这是我使用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令牌(JWT)作为用户标识和身份验证令牌


3
我猜#3应该是/debug_token,因此您可以检查令牌实际上是否适合您的应用程序。
Peppe LG

2
不要access_token在客户端中请求。使用“代码工作流程”。通过code对MyAPI再拍往返Facebook的交换codeaccess_token。此处对此进行了更彻底的解释:developers.facebook.com/docs/facebook-login/security
omikron

5

我正在尝试回答相同的问题,并且最近一直在阅读大量内容...

我没有“ the”答案,但是事情对我来说变得更加清楚了。你读过评论吗您提到的文章中吗?我发现它们真的很有趣并且很有帮助。

结果,鉴于自撰写第一篇文章以来事情发展的样子,我想我会做的是:

  • 到处都是HTTPS-这使您无需考虑HMAC,签名,随机数,...

  • 使用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那样

看起来好点吗?


1
谢谢您的回复!我已经考虑过您所说的大部分内容,但是使用FB iOS SDK然后发送Facebook用户ID时,我主要担心的是,将所需的任何ID发送到您的API端点并声称是另一个用户?这就是我通常会陷入困境的地方
亚当

确实!那真是愚蠢,我不考虑这一点...所以解决方案必须以某种方式通过您自己的身份验证服务器...
Olivier Lance

我已经用另一个解决方案的主意更新了我的答案...但是只是意识到您已经在原始问题中提到了它!我现在什么都看不到...
Olivier Lance 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.