【发布时间】:2015-02-02 08:10:49
【问题描述】:
前言
我正在开发几个 Web 服务和一些客户端(Web 应用程序、移动设备等),它们将通过 HTTP(s) 与所述服务交互。我目前的工作项目是为产品设计一个认证和授权解决方案。我已决定利用 Facebook、Google、Microsoft、Twitter 等外部身份提供商进行身份验证。
我正在尝试解决“当请求到达我的服务器时,我如何知道用户是谁以及如何确定?”的问题。下面还有更多问题...
要求
- 依靠外部身份来表明我正在与谁打交道(基本上我只关心“userId”)。
-
系统应使用基于令牌的身份验证(与例如 cookie 或基本身份验证相反)。
我相信这是在提供松散耦合的同时跨多个客户端和服务器进行扩展的正确选择。
工作流程
根据我对基于令牌的身份验证的阅读和理解,以下是我想象的工作流程。现在让我们关注网络浏览器中的 Facebook。我的假设是其他外部身份提供者应该具有类似的功能,尽管我还没有确认。
注意,在撰写本文时,我的以下内容基于 Facebook 登录版本 2.2
- 客户端: 使用JavaScript SDK 发起登录 Facebook
- Facebook:用户验证并批准应用权限(例如访问用户的公开个人资料)
- Facebook:向客户端发送包含用户访问令牌、ID 和签名请求的响应
- 客户端:将用户访问令牌存储在浏览器会话中 (handled by SDK conveniently)
- 客户端:通过在授权标头中发送用户的访问令牌 + 用户 ID(可能在自定义标头中)向我的 Web 服务发出安全资源请求
- 服务器:从请求头读取用户访问令牌,并通过向 Facebook 提供的 debug_token 图 API 发送请求来启动验证
- Facebook:使用用户访问令牌信息(包含 appId 和 userId)回复服务器
- 服务器:通过将 appId 与预期(自身已知)和 userId 与客户端请求发送的内容进行比较来完成令牌验证
- 服务器:用请求的资源响应客户端(假设是快乐的授权路径)
我想象步骤 5-9 将重复对服务器的后续请求(而用户的访问令牌是有效的 - 未过期、从 FB 端撤消、应用程序权限更改等)
这里有一个图表可以帮助您完成这些步骤。请理解此系统不是单页应用程序 (SPA)。提到的 Web 服务本质上是向客户端提供 JSON 数据的 API 端点;它们不提供 HTML/JS/CSS(Web 客户端服务器除外)。
问题
首先,根据我的前言和要求,所描述的方法是否存在明显的差距/坑?
-
是否需要/推荐向 Facebook 执行出站请求以验证访问令牌(上述步骤 6-8)每个客户端请求?
我至少知道,我必须验证来自客户端请求的访问令牌。但是,我不知道在第一次之后进行后续验证的推荐方法。如果有典型的模式,我有兴趣了解它们。我了解根据我的要求,它们可能取决于应用程序;但是,我只是不知道要寻找什么。一旦我有了一个基本的想法,我就会进行尽职调查。
例如,可能的想法:
在第一次验证完成后散列访问令牌 + 用户 ID 对,并将其存储在分布式缓存中(所有 Web 服务器均可访问),有效期等于访问令牌。根据来自客户端的后续请求,对访问令牌 + userId 对进行哈希处理并检查其是否存在于缓存中。如果存在,则请求被授权。否则,请联系 Facebook 图形 API 以确认访问令牌。我假设如果我使用 HTTPS(我会这样做),这种策略可能是可行的。但是,性能比较如何?
this StackOverflow question 中接受的答案建议在 Facebook 用户令牌的第一次验证完成后创建自定义访问令牌。然后将自定义令牌发送到客户端以进行后续请求。但是,我想知道这是否比上述解决方案更复杂。这将需要实现我自己的身份提供者(我想避免这种情况,因为我想首先使用外部身份提供者......)。这个建议有什么好处吗?
-
上述第 3 步中的响应中是否存在signedRequest 字段(提到here),相当于“游戏画布登录”流程中的签名请求参数here?
它们似乎被暗示为等效,因为前者在文档中链接到后者。然而,令我惊讶的是,游戏页面上提到的验证策略并没有在网络文档的“手动构建登录流程”page 中提及。
-
如果 #3 的答案是“是”,是否可以使用相同的身份确认策略来解码签名并与服务器端预期使用的策略进行比较?
我想知道是否可以利用它而不是对 debug_token 图 API 进行出站调用(上面的步骤 #6)来确认推荐的访问令牌here:
当然,为了在服务器端进行比较,签名的请求部分需要与请求一起发送到服务器(上面的第 5 步)。除了在不牺牲安全性的情况下的可行性之外,我想知道与拨打电话相比性能如何。
当我这样做时,例如,在什么场景/出于什么目的,您会将用户的访问令牌持久保存到数据库中吗? 我没有看到需要这样做的场景,但是,我可能忽略了一些东西。我很好奇一些常见的场景可能会引发一些想法。
谢谢!
【问题讨论】:
-
您在 2014 年提出了您的问题。五年后(现在是 2019 年)您实施了什么?很想知道,您的大纲是否与您最终所做的差不多?
标签: facebook security authentication facebook-access-token facebook-authentication