如何在RESTful API中使用OpenID?

33

我正在使用基于Pylons框架的Web应用程序实现RESTful API,目前该应用程序缺乏任何身份验证。因此,我打算实现身份验证并为避免存储用户密码时的所有麻烦和注意事项,我想使用OpenID进行身份验证。如何最好地实现这一点?这两个东西是兼容的吗?是否有现有的使用OpenID的REST API可以供我借鉴?

3个回答

34

我已经花了一些时间研究选项,并想总结一下我的发现。首先,为了更好地理解,让我简单介绍一下背景--我开发和控制着服务和API消费者。消费者是基于Flash的应用程序,从目前API所在的同一主机提供服务,并且应该在浏览器中使用。目前还没有第三方客户端。

因此,这个问题可以分为两个部分:

  • 如何通过API进行OpenID身份验证
  • 如何在后续请求中维护“已认证”状态

对于第一部分,OpenID身份验证几乎总是包括交互式步骤。在身份验证过程中,很可能会有一个步骤,用户需要进入OpenID提供商的网页,登录并按下某个“同意”按钮。因此,API不能且不应该在后台透明地处理此过程(没有“告诉我你的OpenID提供商和密码,我将为您完成其余工作”的功能)。它最好能做的就是传递HTTP链接,客户端必须打开并遵循其中的说明。

维护“已认证”状态

REST API应该是无状态的,每个请求都应包含处理它所需的所有信息,对吧?针对每个请求进行OpenID提供商身份验证毫无意义,因此需要某种类型的会话。一些通信会话密钥(或“访问令牌”或用户名/密码)的选项如下:

  • HTTPS + BASIC身份验证(在每个请求中包含“Authorization:Basic…”头)
  • 亚马逊风格签署请求(在每个请求中包含“Authorization:AWS…”头)
  • OAuth:获取访问令牌,将其及其他一些参数包含在每个请求中
  • 存储会话密钥的Cookie(在每个请求中包含“Cookie:…”头)
  • 在Cookie本身中存储会话信息的已签名Cookie

目前只有一个API消费者,所以我选择了最简单的方法--使用cookie。在Pylons中,借助Beaker,使用它们非常容易。在Flash应用程序中,“cookies”也可以“直接工作”,因为它在浏览器内运行,浏览器会将相关的cookie包含在Flash应用程序发出的请求中--该应用程序不需要在这方面进行任何更改。以下是一篇StackOverflow的问题,其中也推荐使用 cookies:RESTful authentication for web applications

Beaker还具有仅cookie会话的良好特性,其中所有会话数据都包含在cookie中。我猜这就是无状态的极致了。服务器上没有会话存储。Cookie被签名并可选地加密,以避免客户端篡改。缺点是cookie变得有点大,因为现在它需要存储除会话密钥以外的更多内容。通过删除会话中我实际上不需要的一些内容(来自OpenID身份验证的残留),我将cookie大小减少到约200个字节。


4

OAuth 是API使用的更好选择。以下是Python中使用OAuth的示例:oauth-python-twitter。Leah Culver的python-oauth库是Python中OAuth的标准实现,但python-oauth2是一个近期备受关注的竞争者。至于灵感,django-piston支持在为Django创建RESTful API时使用OAuth进行身份验证,尽管针对该特定主题的文档不够完善。


1
API目前针对客户端-服务器场景。客户端是Flash应用程序,服务器是Pylons Webapp。目前没有服务器到服务器的东西,所以现在还不需要三条腿的东西。我的当前问题是如何在系统中引入“经过身份验证的用户”,而无需处理存储密码,发送密码提醒,重置密码等等。OAuth在这里如何帮助我并不明显,因为在两条腿的版本中,它只指定了如何签署请求。 - Pēteris Caune
1
在这种情况下,也许 http://pylonshq.com/pasties/by_tag/openid 中的某个剪贴板可以提供帮助。 - Hank Gay

2
如果您正在构建API,可以检查OAuth协议。它是OpenID的补充。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接