OAuth2.0及token刷新流程


最近面试遇到了客户端授权登陆流程的问题,于是记录一下,目前最流行的方案就是OAuth2.0了。

一、首先来看一下OAuth2.0的原理

OAuth 2.0 是一种授权机制,主要用来颁发令牌(token)。而在传统的客户端-服务端授权模型中,客户端想要请求服务端受保护的资源就必须通过资源拥有者的凭证。但是为了提供给第三方应用访问资源的权限,那么资源拥有者就必须把这个凭证共享给第三方,此时会出现几个问题:

1、第三方应用需要存储资源拥有者的凭据以供以后使用,通常密码以明文形式。

2、服务端需要支持密码认证,尽管这种来自密码的安全性比较弱。

3、第三方应用获得资源的广泛的权限,是的资源拥有者不能限制访问时间和权限。

4、资源拥有者不能中断单个第三方的访问权限,除非中断所有的第三方权限,这时就必须修改密码了。

OAuth通过引入authorization层解决了这些问题,并且将资源拥有者和客户端这些角色分离开来。替代使用资源拥有者的凭据,而是使用一个权限令牌token,它具有具体的范围限制,生命周期,以及其他的权限属性。

OAuth定义了四个角色:分别是resource owner、resource server、client、authorization server。

resource owner 是可以授权资源权限的一个实体,一般指的是终端用户;

resource server 是部署资源的服务器,它可以接收并且响应对资源的携带token的请求;

client 是指应用,比如服务端应用,桌面应用,或者其他的设备应用;

authorization server 它是发行token给client的服务器;

这四个角色直接的交互可以参考下图

这是从请求授权,到生成token并访问数据资源的完整的流程示意图

步骤:

  (A) 客户端应用向资源拥有者申请授权

  (B) 资源拥有者同意授权 

  (C) 客户端拿到同意授权的许可向授权服务器请求获取令牌token

  (D) 授权服务器授权成功生成token并返回给客户端

  (E) 客户端使用token请求资源服务器,一般token放于请求头中

  (F) 资源服务器返回客户端需要的数据资源,到此流程结束

在此流程中以后的请求中,有一个重要的环节,就是刷新token,我们不能每次请求数据都要重新授权获取新的token,这样浪费资源,也不合理。

OAuth 2.0 允许用户自动更新令牌。具体方法是,授权服务器发行令牌的时候,一次性发行两个令牌,一个用于获取数据,另一个用于获取新的令牌(refresh token 字段)。令牌到期前,用户使用 refresh token 发一个请求,去更新令牌。

二、具体的刷新token的实现流程

一般是用户通过账号和密码登陆系统,用户就可以正常操作了,但是登陆授权生成的token是有时效性的,如果token过期了就不能继续访问了,这时为了避免用户频繁的登陆授权,就采用了定期刷新token来保持用户处于登陆状态,这对于用户来说是无感的。

1、通过账号密码登陆后,会获取到token(授权令牌)、refresh_oken(用于刷新token的令牌)、expire_time(令牌token的时效)这三个信息,将这三个连同登陆的时间点(login_time)保存下来以供后续刷新token使用。

2、在以后的操作过程中,每次请求接口时,都检查当前时间current_time与登陆时间login_time的时间差与时效expire_time的大小,如果current_time-login_time大于expire_time亦或者某个阀值,则就使用refresh_token去重新获取token,来更新本地存储的token以达到刷新的目的。

注意一点是,refresh_token的失效性要比token的时效性长很多,这样可以实现token的一直刷新了;但是如果用户长时间为操作,那么refresh_token也过期了,就会强制用户登出。

 另外在刷新token时,还有一个方案,一般是使用轮询机制,定期请求刷新token,此方法实现起来稍微简洁些。

参考:https://blog.csdn.net/hfhwfw161226/article/details/106904834/

相关