前言
token 本身的机制及安全性本文就不赘述,感兴趣的朋友可以百度自行了解。接下来讲下前端如何使用axios
进行无感刷新jwt。
大致思路如下:
- 使用
axios
请求拦截器请求接口时,需要将token
带入到请求头以便后端去验证。 - 在
axios
响应拦截器中,当一个或多个接口响应token
超时并返回特定状态码时,其中一个接口执行更新token接口,其余的响应拉入队列(数组)中,异步等待更新token接口执行完毕,再执行队列(重新请求队列中的接口并将返回的数据return
出去),再置空队列以便下次。
代码如下
看不懂的注释中会体现,代码不多,可以尝试理解下。
//请求拦截器 发送前
axios.interceptors.request.use((config) => {
// 判断是否有token并在请求头携带
let token = JSON.parse(localStorage.getItem('token')),
// console.log('token', token)
config.headers = {
'Content-Type': 'application/x-www-form-urlencoded',
authorization: (token && token.authorization) || null,
};
return config;
});
//响应拦截器 发送后
let updateTokenTag = true,requestArr = [];
axios.interceptors.response.use(
async (response) => {
// console.log(response);
switch (response.data.code) {
// 登录超时,重新授权
case 10001:
console.log('登录超时!');
// 登录超时 获取新授权码,只执行一次
if (updateTokenTag) {
updateTokenTag = false;
// 执行更新token接口
const res = await Http['login'].upAuthorization();
// Utils.setLocal 为存储localstorage方法
Utils.setLocal('token', {
authorization: res.data.authorization,
});
// 执行完更新操作 再去执行刚刚并行加入的列队
requestArr.forEach((execute) => execute());
// 置空队列数组
requestArr = [];
updateTokenTag = true;
// 这里是第一次执行进入更新token的接口继续往下执行
const firstApi = await axios.request(response.config);
return Promise.resolve(firstApi);
} else {
// 通过异步将并行的接口加入队列中,等上面更新完token接口再执行队列
return new Promise((resolve) => {
// 用函数的方式将相应数据resolve出去,执行函数就能得到响应结果
requestArr.push(() => {
return resolve(axios.request(response.config));
});
});
}
break;
}
//无超时这里直接输出了结果
return Promise.resolve(data);
},
(err) => {
// 执行错误操作
console.log(err)
}
);
以上就是实现的思路及代码。