JWT如何实现无感刷新

1.不能修改前端jwt内容时

可以使用redis来作为过期时间的判断,当用户登录后,为其生成一个jwt,这个jwt不用设置过期时间,同时,我们根据用户信息和用户的环境信息(IP、物理地址)等通过摘要算法,比如MD5生成redis的key,同时为其设置过期时间,比如2小时。

当用户访问系统时,需要携带这个jwt,一般使用请求头携带,然后同样的使用摘要算法得出用户存储在redis中的key,然后判断该key是否过期,如果已经过期,说明用户已经很久没有发起过请求了,这时就要求用户重新进行登录。

如果key过期时间小于1小时,那么就修改redis数据库中该key的过期时间,比如加上1小时。

2.可以修改前端jwt

使用refresh_token和access_token两个token,access_token负责业务处理,refresh_token用于判断是否过期。

当用户登录时,为其签发两个token,一个是过期时间短的access_token,一个是过期时间长的refresh_token。

当用户发起请求时,必须携带这两个token。

当access_token未过期时,可以直接利用access_token中的信息进行业务处理

当access_token过期,而refresh_token未过期时,我们可以先解析refresh_token中的用户信息并放入ThreadLocal中,后续在Controller中用refresh_token中的信息来完成业务处理,这样就可以避免发送两个请求来完成一个业务。

此外还需要签发新的两个token,该过程可以通过HandlerInterceptor或者Filter来完成,我们可以通过代码获取access_token和refresh_token本来的过期时间,在这个基础上加上一段时间来签发新的token,由于jwt是无状态的,我们可以根据之前的jwt内容来进行签发token,而不需要重新查询数据库。签发的token我们可以将其放入响应头中,响应头的名称可以自己命名。但是,需要注意的是,后端响应给前端的响应头一般在前端是获取不到的,这是因为规范的原因,所以如果需要将自己命名的请求头暴露给前端的话,必须修改Access-Control-Expose-Headers响应头来将这两个响应头给暴露出来,让前端可以获取响应头的内容。

以Authorization,RefreshToken两个响应头为例子

    response.setHeader("Access-Control-Expose-Headers","Authorization,RefreshToken");
    response.setHeader("Authorization", newAccessToken);
    response.setHeader("RefreshToken", newRefreshToken);

前端获取到响应头的内容后,可以就地修改在浏览器中存储的两个旧token为新token

我采用的方法是使用axios响应拦截器,在响应被处理前判断响应中是否包含Authorization和RefreshToken这两个响应头,如果响应头存在,那就是提醒我们更换token了,我们直接在响应拦截器修改token就可以了。

当refresh_token也过期时,说明用户已经很久时间没有操作了,这个时候可以要求用户重新登录。

这种方式可能存在逻辑上的问题,比如在很短的时间内发送两个请求,可能会导致前一个请求生成的token被后一个请求生成的token给覆盖了,还有可能由于修改token顺序的问题,导致access_token是前一个请求的,而refresh_token是后一个请求的,虽然对业务不会造成影响,但是在逻辑上是存在问题的。

对于这种情况我们可以使用一个计时的Map结构来存储过去几秒钟的原始jwt和生成的新的jwt,这样,当相同的jwt请求到来时可以不用签发新的token,而是直接返回Map中存储的新token,并使用这个新token来完成业务而不是旧token,因为如果旧token刚好处在临界时间的话可能会导致一个请求成功了,而一个请求失败了。

计时Map的结构:Map

key:value = 旧token:新生成的token 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值