前言
网上搜索到的常见处理方式是在axios响应拦截器中获取401状态码后,使用refresh token发送请求,获取新的token。考虑到设置的refresh token也会过期,以及为了减少请求错误,因此在请求拦截器中对token是否过期进行预先判断。
思路
首先判断access token是否过期,未过期则添加到headers。如果access已过期,再判断refresh token是否过期,未过期则发送请求获取新的access token,过期则退出登录。
解决方案
import dayjs from "dayjs";
import jwt_decode from "jwt-decode";
import store from "@/store";
const storage = localStorage;
const axiosInstance = axios.create({
baseURL: 'http://localhost:8000',
withCredentials: true,
});
axiosInstance.interceptors.request.use(
async config => {
const token = store.state.auth.token;
const isAccessExpired = token ? dayjs.unix(jwt_decode(token).exp).diff(dayjs()) < 1 : true;
const refresh = storage.getItem('refresh.myBlog');
const isRefreshExpired = refresh ? dayjs.unix(jwt_decode(refresh).exp).diff(dayjs()) < 1 : true;
if (token !== null) {
if (!isAccessExpired) {
// token 未过期,添加到 headers
config.headers.Authorization = `Bearer ${token}`
} else {
// token 过期,判断 refresh 是否过期
if (!isRefreshExpired) {
// refresh 未过期,获取新的 access
const response = await axios.post(
`${baseURL}/api/token/refresh/`,
{refresh: refresh}
)
store.commit('auth/SET_TOKEN', response);
config.headers.Authorization = `Bearer ${store.state.auth.token}`
} else {
// refresh 过期,退出登录
store.commit('auth/REMOVE_TOKEN');
}
}
}
return config;
},
error => {
return Promise.reject(error.response);
}
)