OAuth详解之二:过程

上篇文章介绍了OAuth协议大致的工作流程。本文对这个过程做个细化。

我们已经知道,客户端在获得资源的访问令牌(token)前,需要获得授权服务器的授权。一个问题是,通信双方怎么保存这个授权的状态呢?也就是说,服务器给你授权了,怎么告诉你呢?这需要一个授权码(authorization code)。注意,这时候还没有token。简单地讲,授权服务器在通过资源拥有者的认证后,授权给客户端,返回一个跳转URI(redirect uri)。这个uri里面包含了一个授权码。客户端加载这个uri,拿到授权码,进而向授权服务器的token组件(token endpoint)发起请求,获得一个访问令牌。如图2.1所示。

OAuth详解之二:过程

下面来分析下具体的交互过程。授权服务器在接到来自客户端的授权请求后,会产生这样的响应:
一个来自授权服务器的HTTP响应header的内容如下:
OAuth详解之二:过程

状态码是302,即是一个重定向指令。注意其中的Location字段,这次重定向的目标就是Location的值。response_type表示授权的类型是授权码(code),redirect_ui字段就是前面提到的跳转URI,这个URI会在下次重定向用到。scope字段定义了客户端需要哪些授权,是一个资源访问权限的列表(比如读写权限),以空格分隔。这个列表是资源服务器定义的,授权服务器在授权过程中就可以授予或拒绝特定的scope。注意此时依然没有授权码。接下来客户端就会发起一个GET请求到授权服务器获取授权码。

OAuth详解之二:过程

作为响应,授权服务器依然会返回一个跳转指令。这个响应对应的跳转URI里面就包含了授权码,通常在code字段中:

OAuth详解之二:过程

最后,客户端再发一次GET请求。我们可以看到,这次跳转就是不是客户端向授权服务器发请求了,而是直接向应用程序的Web服务器发请求。这样用户登录的Web应用程序(无论是浏览器还是服务器)就拿到了这个授权码,留待后续使用。另外,客户端还会检查state字段的值是否与上一步重定向中的state值相同。

OAuth详解之二:过程

从上面过程看出,获取授权码经历了两次重定向和两次GET请求,目的就是让应用程序拿到授权。可以这样理解,第一次重定向是授权服务器告诉客户端你怎样向我发起请求能拿到授权码。那么客户端就按照要求发起一个GET请求。第二次重定向是服务器告诉客户端,授权码在这个URI里,你再请求一次就拿到了。于是客户端又GET了一次,就拿到了授权码。这就是协议的特点:双方需要商议信息交换的方式。
下面开始获取访问令牌。
客户端这次发起一个POST请求如下:
OAuth详解之二:过程

请求中包含了Basic认证的信息和刚刚获得的授权码等信息。授权服务器的token模块接收到这个请求后,进行了一系列的工作。首先,它要查看Basic认证信息,确认发起请求的客户端是谁。为什么这里还需要一步认证呢?实际上,服务器是想确认请求token的这个客户端与刚才请求授权码的那个客户端是不是同一个人。如果不是,就视为非法的请求。这也合理,我授权给另一个人,你凭什么申请token。服务器还会检查授权码是否是有效的,是不是已经使用过的等等。所有这些检查工作结束后,服务器会返回一个token给客户端:

OAuth详解之二:过程

注意,这里的token类型指定为Bearer Token,为OAuth多数情况下使用的token类型,bear是承载、持有的意思,说明这个token就是请求资源所必须携带的。token包含客户端的请求信息,请求的资源信息,授权的用户信息等,有关Bearer Token的详情后面会有解读。除了Bearer以外,服务器还可能返回refresh token,目的是在不重新获得授权的情况下刷新token,这个马上会讲到。客户端拿到token后,存储在安全的地方,然后就可以使用它访问服务器资源了。通常这样使用:

OAuth详解之二:过程

资源服务器会解析这个请求并检查token,看是否依然有效,查询是谁授权的,以及授权用于做什么,根据这些信息进行响应。当授权服务器生成token的时候会将其写入数据库,资源服务器会到这个服务器查询token信息。下面来谈谈token的刷新机制。
refresh token不是用来直接请求资源的,而是用来请求新的Bearer Token的。有时因为一些原因(过期,系统内部机制,用户回收等)会导致已有的token失效,这时需要重新获取token。如果用失效的token请求资源,资源服务器会返回错误信息。那就需要资源拥有者重新授权然后获取token,但你不能保证资源拥有者始终注意token的有效性。在OAuth 2.0版本里,原来的token会自动过期,然后使用refresh token请求新的Bearer Token。如图2.10所示。
OAuth详解之二:过程

当然,如果refresh token本身失效了,就只好等待用户重新授权了。

至此,客户端作为用户的代理可以正常访问资源了。这个过程里面其实还有很多细节值得探究,比如token是如何生成的,授权码如何产生以及检查的,授权服务器如何认证用户的等等。这些问题我会在后面文章继续学习和分享。
如理解有误,欢迎不吝赐教。