Oauth2为什么不能跳过Code获取而直接获取Token?
首先,我们都知道,Oauth2整体思路是,在客户端与数据存储的服务端中间添加了一个授权层,客户端不能直接访问数据存储的服务端,只能登录到授权层,将认证和授权分隔开来。客户端访问服务端存储的数据需要携带认证层返回的code。
总之,一句话,”客户端”登录授权层以后,”服务提供商”根据令牌的权限范围和有效期,向”客户端”开放用户储存的资料。
Oauth2的运行流程
(A)用户打开客户端以后,客户端要求用户给予授权。
(B)用户同意给予客户端授权。
(C)客户端使用上一步获得的授权,向认证服务器申请令牌。
(D)认证服务器对客户端进行认证以后,确认无误,同意发放令牌。
(E)客户端使用令牌,向资源服务器申请获取资源。
(F)资源服务器确认令牌无误,同意向客户端开放资源
一种很常见的授权模式即为第三方登录使用的授权码模式,该模式的流程图如下:
(A)用户访问客户端,后者将前者导向认证服务器。
(B)用户选择是否给予客户端授权。
(C)假设用户给予授权,认证服务器将用户导向客户端事先指定的”重定向URI”(redirection URI),同时附上一个授权码code。
(D)客户端收到授权码,附上早先的”重定向URI”,向认证服务器申请令牌。这一步是在客户端的后台的服务器上完成的,对用户不可见。
(E)认证服务器核对了授权码和重定向URI,确认无误后,向客户端发送访问令牌(access token)和更新令牌(refresh token)。
为什么要使用code这步中间步骤
说了这么多Oauth2的流程,那具体是什么原因使得我们不能直接去访问服务端得到token呢?
其实主要的原因很简单,我们来使用反证法来考虑一下。首先得注意到的是,认证服务器的返回是通过 302 重定向实现的,也就是说,返回的code值是显示在url上的,假如我们不用code,客户端请求之后直接获得访问令牌(access token),那么token将会显示在url上,中间人就很容易截获token,token的失窃风险急剧上升。
此外,我们用 code 换取 token,不需要借助用户浏览器,是由 client 后台直接访问授权服务器的,这个步骤 client 还需要发送自己的 app secret,授权服务器也需要使用这个 app secret 来验证 client 的身份
如果在用户登陆时就要返回 token,那么 client 将不得不生成一个包含自己 app secret 的授权地址,那么 client 的 app secret 任何人都可以通过浏览器url地址栏看到了,对 client 来说也不安全