Oauth2的授权码模式为什么返回token之前先返回code,而不是直接返回token?

所谓第三方登录,实质就是 OAuth 授权。用户想要登录 A 网站,A 网站让用户提供第三方网站的数据,证明自己的身份。获取第三方网站的身份数据,就需要 OAuth 授权。

举例来说,A 网站允许 GitHub 登录,背后就是下面的流程。

  1. A 网站让用户跳转到 GitHub。
  2. GitHub 要求用户登录,然后询问"A 网站要求获得 xx 权限,你是否同意?"
  3. 用户同意,GitHub 就会重定向回 A 网站,同时发回一个授权码。
  4. A 网站使用授权码,向 GitHub 请求令牌。
  5. GitHub 返回令牌.
  6. A 网站使用令牌,向 GitHub 请求用户数据。

那为什么不直接返回token?而要中间经过code再倒腾一遍呢?知乎上有位大哥回答得挺好。

问题:

为什么oauth2中的授权码模式 在获取token之前非要先到资源服务器获取一个code 然后才使用资源服务器的code去资源服务器去申请token?

看了很多资料说是因为 用户在确认授权之后 资源服务器会跳转到我们指定的一个回调url, 如果直接返回token的话,谁都可以在浏览器中看到这个token 那就没有安全性可言了

但是我有个想法不知是否可行 那就是为什么 资源服务器非要跳转到第三方站点给的回调url呢? 我的url如果是个接口 资源服务器完全可以不通过浏览器跳转 而是直接回调我的接口 直接吧token给我的服务器, 然后我的服务器存储好token之后 自己决定如何跳转不就行了? 这样岂不是比授权模式简单也比隐式模式安全

回答:

首先,从产品交互上,我们需要浏览器跳转到“认证服务器”,让用户明确表态同不同意“第三方站点”的授权请求。这个时候,浏览器访问的地址已经到“认证服务器”去了,不跳转回来的话,网页不在“第三方站点”的控制中,怎么进行授权成功后的下一步交互呢?

授权码模式的安全考量,是基于产品交互能完成的前提下,考虑如何不在浏览器这种暴露 url 的环境里做到安全的。

如果你想表达的是“认证服务器”跳转回来,但是不带 code,而是通过 Server 对 Server 将 token 直接给“第三方服务器”。

这样会造成一系列问题:

  1. Http 协议是无状态的,“第三方服务器”无法从一个 Server 对 Server 的请求轻易区分这个 token 对着自己当前哪个 Session。

  2. 如果依赖第一步里,“第三方服务器”跳转到“认证服务器”时传递的 GET 参数来作为 Session 身份区分,又涉及到跳转本身就是明文,可能被篡改的问题,需要协定复杂的签名协议来保证安全,这和 OAuth2 希望设计简洁验证模式的初衷违背。

  3. 假设安全问题解决了,已跳转回来的“第三方服务器”网页需要等待一个不知道何时才会过来的“认证服务器” Server 回调,才能告诉用户到底授权成功没有。远不如同步主动去请求“认证服务器”获取方便。

总结:1. github重定向回来的参数是明文的。2. 这样设计更方便

版权

评论