86

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

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

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

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

我已经阅读并研究了很多关于 REST API 的标准身份验证方法。我们不能使用诸如Basic Auth over HTTPS之类的方法,因为这样的用户没有凭据。像这样的东西似乎只用于使用 API 验证应用程序。

目前,我能想到的最好方法是在我们的 API 上点击 /authorize 端点,它重定向到 Facebook OAuth,然后重定向回站点并提供 API 用户可以用来验证后续身份的“令牌”要求。

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

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

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

4

3 回答 3

100

更新:见下文

我也一直在认真思考这个问题。我还不完全清楚,但这是我正在考虑的路线。我正在创建一个 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. 创建我自己的访问令牌,保存它并将其返回给客户端,以便从现在开始使用
于 2012-11-18T20:55:05.747 回答
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) 作为用户标识和身份验证令牌

于 2016-05-22T18:17:36.810 回答
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 所做的那样

看起来更好?

于 2012-09-03T17:38:40.583 回答