OAuth2.0实现原理

153 阅读3分钟

授权码(Authrization Code)模式

image.png

1.用户访问应用前端页面,请求到达应用后端,发现没有access_token,后端会将请求重定向到认证服务器,认证服务器会给应用前端返回自己的页面,用户在认证服务器的页面点击确认以后。认证服务器会给前端页面返回一个授权码【这里不直接返回token,因为前端是不安全的,本地数据可能被窃取】

2.应用前端页面拿到授权码以后,带着授权码请求应用服务器,应用服务器通过前端的授权码和自己的secret去认证服务器换取access_token。这种模式,即使前端页面被破解,第三方拿到授权码,也没办法获取token,因为它没有secret。

授权码模式的底层逻辑,就是不信任应用的客户端,只信任应用的服务端。一般这种模式使用比较多

refresh_token和access_token

image.png

access_token 时效短, refresh_token 时效长, 比如 access_token 有效期1个小时, refresh_token 有效期1天

第一次获取access_token的时候,需要用户操作,拿着用户操作后得到的授权码和secret去认证服务器获取access_token。

当access_token过期以后,应用服务器,可以不经过用户操作,直接拿着之前的refresh_tokenu去认证服务器获取新的access_token,从而继续访问受保护的资源。但是refresh_token的过期时间是固定的,无法延续。

接下来, 我们继续看两个令牌在下面场景的应用, 假设有一个用户需要在后台管理界面上操作6个小时。

1 颁发一个有效性很长的 access_token, 比如 6 个小时, 或者可以更长, 这样用户只需要刚开始登录一次, access_token 可以一直使用, 直到 access_token 过期, 然后重复, 这种是不安全的, access_token 的时效太长, 也就失去了本身的意义。

2 颁发一个1小时有效期的 access_token, 过期后重新登录授权, 这样用户需要登录 6 次, 安全倒是有了, 但是用户体验极差

3 颁发1小时有效期的 access_token 和6小时有效期的 refresh_token, 当 access_token 过期后(或者快要过期的时候), 使用 refresh_token 获取一个新的 access_token, 直到 refresh_token 过期, 用户重新登录, 这样整个过程中,用户只需要登录一次, 用户体验好。

access_token 泄露了怎么办? 没关系, 它很快就会过期。
refresh_token 泄露了怎么办? 没关系, 使用 refresh_token 是需要客户端秘钥 client_secret 的。

举例:颁发1小时的access_token和6小时的fresh_token,如果用户一直在操作,则它一共会有5次用refresh_token换取access_token的操作。这个操作在应用服务端,用户不感知。refresh_token存在的原因,就是怕服务端的access_token泄漏,所以采取降低access_token有效期的方式,来降低泄漏的损失。
【从某种角度来讲,授权码的存在是因为不信任客户端,fresh_token的存在是因为不信任服务端】

4 用户登录后, 在后台管理页面上操作1个小时后, 离开了一段时间, 然后 5个小时后, 回到管理页面继续操作, 此时 refresh_token 有效期6个小时, 一直没有过期, 也就可以换取新的 access_token, 用户在这个过程中, 可以不用重复登录。但是在一些安全要求较高的系统中, 第二次操作是需要重新登录的, 即使 refresh_token 没有过期, 因为中间有几个小时, 用户是没有操作的, 系统猜测用户已离开, 并关闭会话。

refresh_token的不可延续性:
另外, 在 OAuth 2.0 安全最佳实践中, 推荐 refresh_token 是一次性的, 什么意思呢? 使用 refresh_token 获取 access_token 时, 同时会返回一个 新的 refresh_token, 之前的 refresh_token 就会失效, 但是认证服务器要保证两个 refresh_token 的绝对过期时间是一样的, 这样就不会存在 refresh_token 快过期就获取一个新的, 然后重复,永不过期的情况。

image.png