第五章:认证(2)
第四章中,我们提到大多数网站使用用户名和密码作为身份验证的凭证。我们还讨论到重复使用这些凭证访问API是不安全的,所以API通常需要一个和用户登录网站时使用的不同的凭证集合。常见的例子是密钥。本章,我们来看一下另一个解决方案,开放授权(OAuth),这个是目前web上使用最广泛的验证方案。
让生活更简单
是否有被逼完成下面这样的注册表单的经历?
在上面那样的表单域中输入一长串的密钥的用户体验是非常糟糕的。首先,你必须找到需要的密钥。是的,当你买了软件之后,它就会发送到你的收件箱里,但是一年之后呢,要找到它就很麻烦了(是从哪个邮箱发过来的?我是用哪个邮箱注册的?!)找到之后,你必须准确无误的输入这个可恶的东西——打字错误或遗漏某个字母就会得到一个错误的结果,甚至导致你还没有注册的软件被锁定!
强制用户使用API密钥的体验同样糟糕。输入错误的问题非常常见,并且它要求用户手工完成客户端和服务器之间的部分设置。用户必须从服务器获取密钥,然后给予客户端。由于工具就意味着它应该可以自动工作,所以肯定还有更好的方案。
开始OAuth。OAuth解决的主要问题就是自动完成密钥的交换。它提供了一个标准的方法,用户通过简单的几个步骤就可以让客户端从服务器获取一个密钥。从用户的角度来看,所有的OAuth都需要输入凭证。而客户端和服务器在幕后进行工作,使客户端获取一个有效的密钥。
目前OAuth有两个版本,它们都有一个恰当的名字OAuth 1和OAuth 2。要在和API通信的过程中使用它们进行身份认证,就有必要理解每个版本的步骤。因为它们使用相同的工作流,我们会讨论OAuth 2的步骤,然后指出OAuth 的不同之处。
OAuth 2
我们首先需要了解OAuth交换过程中涉及的角色组件:
用户 — 希望连接两个网站的人
客户端 — 被授权访问用户数据的网站
服务器 — 拥有用户数据的网站
接下来,我们需要给出一个简单的免责声明。OAuth 2的一个目标是允许业务修改认证过程适应自己的需要。由于这种天生的可扩展性,API可以使用略有差异的步骤。下面展示的是一个基于web的应用的常见工作流。手机和桌面应用的流程可能有轻微的差别。
这里就是OAuth 2的步骤。
-
用户告诉客户端去连接服务器
用户通过告诉客户端他希望客户端连接服务器来开始这个流程。通常是以点击一个按钮开始。
-
客户端将用户重定向到服务器
客户端转到服务器的网站,同时携带一个URL,服务器通过该URL转回用户认证的网站,这个URL叫做回调URL。
-
用户登录到服务器,授权客户端访问
用户使用他们的用户名和密码进行服务器认证。服务器现在可以确定它的一个用户请求给予客户端访问这个用户的账户和相关数据的权限。
-
服务器将用户转到客户端,同时携带认证代码
服务器将用户转到客户端(返回到步骤2的回调URL)。在响应中隐藏着给客户端的一个唯一的认证代码。
-
客户端使用认证代码+密钥向服务器交换访问令牌
客户端使用它收到的认证代码创建另一个发送到服务器的请求。请求中包括客户端的密钥。当服务器看到一个有效的认证代码和一个受信任的客户端密钥,它确定客户端就是它所宣称的那个,并且现在它代表一个真正的用户。服务器在响应中返回一个访问令牌。
-
客户端从服务器获取数据
到这个时候,客户端可以代表用户访问服务器。步骤6中的访问令牌本质上就是服务器上用户的另一个密码。客户端在每一个请求中都包括访问令牌,所以它可以直接和服务器进行认证。
客户端刷新令牌(可选)
OAuth 2引入的一个特性就是让访问令牌过期。这种安全性的增强有助于保护用户的账户——令牌过期的时间越短,被盗的令牌可能被恶意使用的时间也就越短,类似于信用卡号码过一段时间就过期。令牌的有效期是由服务器设置的。API可以在几个小时到几个月的时间里自由使用所有资源。一旦有效期结束,客户端必须向服务器申请新的令牌。
OAuth 1 有什么不同
OAuth版本之间有几个主要的区别。其中一个我们已经提过了,访问令牌不过期。
另一个区别是OAuth 1包括了一个额外的步骤。在上文的步骤1和2之间,OAuth 1需要客户端向服务器申请一个请求令牌。这个令牌充当了 OAuth 2 中认证代码的角色,用来交换访问令牌。
第三个区别是OAuth 1需要数字签名。我们会跳过签名如何工作的细节(你可以找到做这个工作的代码库),但是知道为什么一个版本有签名而另一个版本没有还是值得的。请求签名可以保护数据在客户端和服务器之间移动时不会被篡改。签名允许服务器核实请求的真实性。
然而,现在大部分API传输都发生在一个安全的通道上(HTTPS)。认识到这一点之后,OAuth 2取消了签名从而使得版本二更容易使用。取而代之的是OAuth 2依赖于其他的方法来保证传输的数据的安全。
授权
OAuth 2中另一个需要特别注意的概念是限制访问,正式名称叫做授权。返回到第2步,当用户点击按钮允许客户端访问的时候,隐藏在下面的是客户端请求的具体权限。这些权限称为范围,是OAuth2的另一个重要特色。它们为客户端提供了一个方法,客户端可以请求访问用户数据的受限权限,这样用户更容易信任客户端。
范围的强大之处在于这种限制是基于客户端的。API密钥则不同,它的限制是基于密钥的,导致所有客户端都是相同的,OAuth范围允许一个客户端拥有权限X,另一个客户端有权限X和Y。这就是说一个网站可以查看你的通讯录,而另一个网站可以查看也可以编辑。
译自