OAuth详解之二:过程
上篇文章介绍了OAuth协议大致的工作流程。本文对这个过程做个细化。
我们已经知道,客户端在获得资源的访问令牌(token)前,需要获得授权服务器的授权。一个问题是,通信双方怎么保存这个授权的状态呢?也就是说,服务器给你授权了,怎么告诉你呢?这需要一个授权码(authorization code)。注意,这时候还没有token。简单地讲,授权服务器在通过资源拥有者的认证后,授权给客户端,返回一个跳转URI(redirect uri)。这个uri里面包含了一个授权码。客户端加载这个uri,拿到授权码,进而向授权服务器的token组件(token endpoint)发起请求,获得一个访问令牌。如图2.1所示。
状态码是302,即是一个重定向指令。注意其中的Location字段,这次重定向的目标就是Location的值。response_type表示授权的类型是授权码(code),redirect_ui字段就是前面提到的跳转URI,这个URI会在下次重定向用到。scope字段定义了客户端需要哪些授权,是一个资源访问权限的列表(比如读写权限),以空格分隔。这个列表是资源服务器定义的,授权服务器在授权过程中就可以授予或拒绝特定的scope。注意此时依然没有授权码。接下来客户端就会发起一个GET请求到授权服务器获取授权码。
作为响应,授权服务器依然会返回一个跳转指令。这个响应对应的跳转URI里面就包含了授权码,通常在code字段中:
最后,客户端再发一次GET请求。我们可以看到,这次跳转就是不是客户端向授权服务器发请求了,而是直接向应用程序的Web服务器发请求。这样用户登录的Web应用程序(无论是浏览器还是服务器)就拿到了这个授权码,留待后续使用。另外,客户端还会检查state字段的值是否与上一步重定向中的state值相同。
请求中包含了Basic认证的信息和刚刚获得的授权码等信息。授权服务器的token模块接收到这个请求后,进行了一系列的工作。首先,它要查看Basic认证信息,确认发起请求的客户端是谁。为什么这里还需要一步认证呢?实际上,服务器是想确认请求token的这个客户端与刚才请求授权码的那个客户端是不是同一个人。如果不是,就视为非法的请求。这也合理,我授权给另一个人,你凭什么申请token。服务器还会检查授权码是否是有效的,是不是已经使用过的等等。所有这些检查工作结束后,服务器会返回一个token给客户端:
注意,这里的token类型指定为Bearer Token,为OAuth多数情况下使用的token类型,bear是承载、持有的意思,说明这个token就是请求资源所必须携带的。token包含客户端的请求信息,请求的资源信息,授权的用户信息等,有关Bearer Token的详情后面会有解读。除了Bearer以外,服务器还可能返回refresh token,目的是在不重新获得授权的情况下刷新token,这个马上会讲到。客户端拿到token后,存储在安全的地方,然后就可以使用它访问服务器资源了。通常这样使用: