我正在使用 RESTful API 构建基于 Pylons 的 Web 应用程序,该应用程序目前缺少任何身份验证。所以我要实现它,为了避免存储用户密码的所有麻烦和谨慎,我想使用 OpenID 进行身份验证。最好的方法是什么?这两件事兼容吗?是否存在使用 OpenID 的现有 REST API,我可以从中获得灵感?
3 回答
我现在花了一些时间研究这些选项,并想总结一下这些发现。首先,多一点上下文——我开发和控制服务和 API 使用者。Consumer 是基于 Flash 的应用程序,由 API 现在所在的同一主机提供服务,并且应该在浏览器中使用。目前还没有第三方客户。
所以这个问题可以分为两部分,
- 如何通过 API 进行 OpenID 身份验证
- 如何在后续请求中保持“已验证”状态
对于第一部分,OpenID 身份验证几乎总是包含交互步骤。在身份验证过程中,很可能会有一个步骤,用户在 OpenID 提供商的网页中,登录并按下“我同意”按钮。所以 API 不能也不应该透明地处理这个问题(不要“告诉我你的 OpenID 提供者和密码,剩下的我来做”)。它可以做的最好的事情是传递和返回客户端必须打开并遵循说明的 HTTP 链接。
保持“已验证”状态
REST API 应该是无状态的,每个请求都应该包含处理它所需的所有信息,对吧?针对每个请求对 OpenID 提供者进行身份验证没有任何意义,因此需要某种会话。用于通信会话密钥(或“访问令牌”或用户名/密码)的一些选项是:
- HTTPS + BASIC 身份验证(每个请求中的“Authorization: Basic ...”标头)
- 签署亚马逊风格的请求(“授权:AWS ...”每个请求中的标头)
- OAuth:获取访问令牌,在每个请求中包含该令牌和一堆其他参数
- 存储会话密钥的 Cookie(每个请求中的“Cookie: ...”标头)
- 将会话信息存储在 cookie 本身中的签名 cookie
现在只有一个 API 使用者,所以我选择了可能可行的最简单的东西——cookie。在Beaker的帮助下,它们在 Pylons 中非常易于使用。它们还在 Flash 应用程序中“正常工作”——因为它在浏览器内运行,浏览器将在 Flash 应用程序发出的请求中包含相关的 cookie——应用程序根本不需要对此进行更改。这里有一个 StackOverflow 问题也提倡使用 cookie:RESTful authentication for web applications
Beaker 还具有cookie-only 会话的不错功能,其中所有会话数据都包含在 cookie 本身中。我想这几乎是无国籍状态。服务器上没有会话存储。Cookie 被签名并可选择加密,以避免在客户端被篡改。缺点是 cookie 变得有点大,因为它现在需要存储的不仅仅是会话密钥。通过删除会话中我并不真正需要的一些内容(OpenID 身份验证的剩余部分),我将 cookie 大小降低到大约 200 字节。
OAuth更适合 API 使用。以下是 Python 中使用的 OAuth 示例:oauth-python-twitter。Leah Culver 的python-oauth库是 Python 中 OAuth 的规范实现,但python-oauth2是最近引起轰动的竞争者。至于灵感,django-piston在为 Django 创建 RESTful API 时支持使用 OAuth 进行身份验证,尽管该特定主题的文档不如我想要的那么好。
如果你构建 API,你可以检查 OAuth 协议。它是 OpenID 的补充。