关于令牌(token)的刷新问题,因为token是有时效的,只要在token过期前,进行刷新确保token一直在时效范围内即可。前段时间做了大文件的批量分片上传,这个上传时间不定,肯定会有超过token时效的情况,这不···爆雷了,在token进行刷新的时候,上传接口会因为token的刷新而报错,导致文件上传失败,进而停止,没办法只能换种刷新token方法,下面记录一下两种方法:
方法一、定时刷新token
这种方法的优缺点就不多说了,如果项目中没有这种持续调用接口的情况下,这种方法可以说很合适,简单省事。
在项目入口文件中(page/index.vue,这个是我这边的),添加定时器,对token进行定时检测,检测token时效是否快要结束进而进行token刷新。(定时器要在文件销毁的时候清理一下)
methods:{
// 实时检测刷新token
refreshToken() {
this.refreshTime = setInterval(() => {
//在这里对token时效进行检测,检测后判断是否进行刷新
// 我这里是60s进行检测一次
}, 60000)
},
},
destroyed() {
clearInterval(this.refreshTime)
},
方法二、在token过期时刷新token
这种方法的优点就是在持续调用接口的时候不用担心token过期而造成接口调用失败!
import axios from 'axios'
import {
refreshToken
} from '@/api/login' // 刷新token接口
//是否正在刷新token
let isRefreshing = false;
//在刷新token期间发起的请求
let retryRequests = [];
// HTTPrequest拦截
axios.interceptors.request.use(config => {
return config
}, error => {
return Promise.reject(error)
})
// HTTPresponse拦截
axios.interceptors.response.use(async res => {
// 获取状态码
const status = Number(res.status);
//在这里判断token是否过期,我这边token过期,status=424
if (status == 424) {
if (!isRefreshing) {
isRefreshing = true;
const {
data
} = await refreshToken().catch(() => {
//刷新token失败,跳转登录页面重新登录
})
//刷新token成功,处理在此期间发起的请求
//存储token
sessionStorage.setItem('access_token', data.data)
isRefreshing = false;
//判断在此期间是否发起过请求,如果有则循环调用
if (retryRequests.length > 0) {
retryRequests.forEach((fun) => fun());
retryRequests = [];
}
//这里处理token过期时的第一个请求,这个请求没有存入数组中所以这里直接调用
let token = data.data;
res.config.headers.Authorization = `Bearer ${token}`;
return axios(res.config)
} else {
//这里是把刷新token期间发起的请求,全部存入数组中,等待token刷新成功后再对这些请求进行处理
return new Promise((reslove) => {
retryRequests.push(() => {
let token = sessionStorage.getItem('access_token');
res.config.headers.Authorization = `Bearer ${token}`;
reslove(axios(res.config))
})
})
}
}
}, error => {
return Promise.reject(error)
})
目前我这边只有这两种刷新token的方法,大家有好的刷新token方法可以留言,借鉴一下!