@eric1989
2016-05-22T11:37:43.000000Z
字数 2901
阅读 706
有这样一种场景,一个用户(假设是QQ),希望让一个第三方的应用(比如说某个论坛),能够得到关于自身的一些信息(唯一用户标识,比如说QQ号,用户个人信息,比如说是一些基础资料,昵称和头像等)。但是在获得这些资料的同时,却也不能提供用户名和密码之类的验证信息。比如说用户不可能将自身的用户名和密码给第三方让第三方到用户中心之类的地方去获取信息。要达到这样的结果肯定有许多的实现方式。而Oatuh2就是实现上述目标的一种规范,或者说是具体实现的指导方案。
首先来了解下Oatuh2中的几个名字,方便下文的阐述。
Oauth2的作用就是让第三方应用在用户(资源持有者)授权的情况下,通过认证服务器的认证,从而安全的在资源服务器上获得对应的用户资源的流程指导。
Oauth2,根据RFC6749文档,大致的流程如下图所示
上图中的client就是第三方应用。可以看到,Oauth的大致思路是一个线性的流程。
在上面的这个流程中,其中第二步,资源持有者如何授权给予第三方应用一个许可就是最为关键的地方。其中RFC6749文档给出4种第三方取得授权许可的方式。
其中授权码模式是步骤流程最为详细严谨的一种模式。而网络上大部分的第三方Oauth2实现都是基于授权码模式的。本文也是主要讲解授权码模式中的相关流程性问题。至于其他的三种模式,读者可以自行参看RFC6749文档。
授权码模式的流程如下图所示
下面来分别讲解其中的几个点
在引导跳转的时候需要携带如下的几个参数
这一步是一个用户行为。目前基本的做法都是让用户在授权页面上输入用户名和密码。为了保证安全性,这个页面需要由https来进行保护。当然,如果有其他的方式来保证用户名密码,以及认证的state参数不会泄露也是可以的。如果用户输入正确的用户名和密码,一般就确认为用户给予授权。
如果用户给予授权,则认证服务器需要生成一个唯一的授权码code。该code的时效性应该比较短,在5分钟以内比较合适。并且该code只能使用一次,下次就会失效。同时,该code与客户端的id,redirect-uri参数是一一对应的关系。认证服务器此时应该让用户重定向至一开始指定的redirect_uri。携带上state和code参数
第三方应用在验证过state参数的正确性后,接着就可以使用code到认证服务器处换取token。这一步,第三方应用需要携带上的参数有
1. code:就是认证服务器给予的code参数
2. appid:客户端的唯一标识
3. redirect_uri:也就是第一步请求中的重定向参数。因为code实际上是与appid和redirect_uri一一对应的。所以用code换取令牌的时候也要携带上这两个参数
4. grant_type: 授权模式,这里固定为"authorization_code"
认证服务器在验证过参数的合法性后,生成一个全局唯一的token,并且返回给第三方应用。返回的内容采用json表示,返回的参数主要有
1. access_token: 用于获取对应资源的令牌
2. expires_time: 该令牌的有效期
3. reflesh_token: 用户获取新的accesstoekn的token。由于accesstoken的有效期比较短,一旦失效,用户需要再走上面的流程是比较繁琐的。为了提升用户体验,可以使用reflesh_token来获取新的accesstoken。不过这个做法,已经有不同的实现方将这个返回参数去掉了。因为实际上reflesh_token也就意味着accesstoekn是永久有效的了。那和直接延长accesstoken的有效期也没有直接区别了。