关于实现token无感刷新的解决方案

本文探讨了在使用JWT进行身份验证时,如何避免长期有效token带来的安全问题,重点介绍了使用双token自动刷新技术,包括旧token获取新token的方法,以及实现过程中如何处理并发请求和无感刷新的挑战。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题引入

在开发中为了安全或满足分布式场景,通常会舍弃原有的session认证手段,而采用jwt(json web token);但是使用token难免遇到token有效期的问题,如果token长期有效,服务端不断发布新的token,导致有效的token越来越多,这必然是存在安全问题的。而token不想session一样,在用户操作时会进行刷新,为了用户体验,这个刷新就需要自己实现。

方案

一、使用旧token获取新token

如果采取单个token的方式要实现token的自动刷新,就必须使用定时器,每隔一段时间自动刷新token,并且这个时候token一定要是没有过期的,因为如果已经过期的token也可以用来刷新,这和长期有效的token也没什么不同。但这种方式存在一定的问题:

  1. 为了保证同一时间,账户只被单个用户登录,后端必然要保证一个账户的多个token只有一个生效,最简单的方式就是使用分布式缓存中间件如redis,而存在并发请求时,可能前一个请求带着的是旧token,此时又到了刷新token的时间,就会产生请求的token与服务端存储的token不一致的问题
  2. 使用定时器是增加了性能的损耗,不是最佳的手段

二、使用双token的方式进行无感刷新

这里重点介绍这种方式,此方案的大致流程为:登录后客户端收到两个token(access_token,refresh_token),其中access_token用来鉴定身份,而refresh_token用来刷新access_token;这就要求了refresh_token要比access_token有效时间要长,并且refresh_token不能用来鉴定身份
使用这种方案又有一下解决方式:

  1. 后端每次响应都响应一个token过期时间,前端进行判断,在token过期前进行刷新,这种方式存在太多不可控因素,如客户端系统时间被修改、长时间没请求导致token过期却未刷新,无法做到无感刷新,并且也存在并发问题
  2. 使用定时器,使用定时器增加的资源的损耗,亏损了性能,不推荐
  3. 在得到token过期的请求时,再发送refresh_token;有点懒加载的意思,这种方案性能最优

具体实现(方案二的第三种方式)

流程

再理一理程序运行的流程:

  1. 首先,登录得到了两个token,并将其存起来
  2. 当access_token过期时,自动发送refresh_token到刷新token的请求路径请求token刷新
  3. 得到新的token之后,将请求重新发送,实现用户无感刷新token

代码

用到的工具函数

//判空
let isEmpty = function(obj) {
   
    return obj == null || obj == "undefined" || obj == "null" || new String(obj).trim() == '';
};
  1. 封装axios
const my_axios = axios.create({
   
    baseURL: '/app',
    timeout: 15000,
    withCredentials: true
});

这里对axios做一个简单的封装,不做过多赘述

  1. 定义请求拦截器,将请求带上token
my_axios.interceptors.request.use(
        req => {
   
        	//判断当前是否存在tokenBo(tokenBo即两个token组成的对象),存在则带上token
        	//isEmpty函数在上方的工具函数中
            
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值