我正在使用以下代码拦截Axios中的每个HTTP调用,以通过在JWT令牌过期时刷新JWT令牌来保持用户登录状态:
const { token } = window.localStorage;
const axiosInstance = axios.create({
baseURL: process.env.VUE_APP_API_ENDPOINT,
withCredentials: false,
headers: {
Accept: "application/json",
"Content-Type": "application/json",
Authorization: token && token.length > 0 ? `Bearer ${token}` : ""
}
});
axiosInstance.interceptors.request.use(request => {
if (request.url.endsWith("refresh")) { // prevent infinite loop
return request;
}
const { expiryDate } = window.localStorage;
const currentTimestamp = Math.round(new Date().getTime() / 1000);
if (expiryDate && currentTimestamp >= expiryDate) {
console.log("token expired.");
return store
.dispatch("auth/refreshToken") // refreshToken action will place the token in localStorage.token
.then(() => {
const newToken = window.localStorage.token;
request.headers.Authorization = `Bearer ${newToken}`;
return Promise.resolve(request);
})
.catch(() => Promise.resolve(request));
}
console.log("token not expired.");
return request;
});
在我在页面加载时添加更多请求之前,这种方法一直工作良好,每个请求都试图刷新令牌,从而导致后端出现错误。我该如何解决这个问题?我进行了很多搜索,但是找到的所有解决方案都是针对interceptors.response
like this one的,我想使用interceptors.request
,因为登录是可选的,如果用户登录,则不会有401响应尚未登录。
编辑:根据下面用户28的回答,代码已更改为:
axiosInstance.interceptors.request.use(async config => {
if (config.url.endsWith("refresh")) {
// if we are making a refresh token call, return it to prevent infinite loop
return config;
}
await axiosInstance.refreshingToken;
const { expiryDate } = window.localStorage; // token expiry date
const currentTimestamp = Math.round(new Date().getTime() / 1000);
if (expiryDate && currentTimestamp >= expiryDate) {
axiosInstance.refreshingToken = store.dispatch("auth/refreshToken"); // this will update the token in localstorage
await axiosInstance.refreshingToken;
}
const { token } = window.localStorage; // grab the token from localstorage
config.headers.Authorization = `Bearer ${token}`;
return config;
});
答案 0 :(得分:1)
您需要一个全局变量来确定是否必须等待。最简单的方法是将其分配给axios实例。
示例代码:
axios.interceptors.request.use(async config => {
if (isRefreshTokenRequest) {
return config
}
if (axios.refreshingToken) {
await axios.refreshingToken
}
if (isTokenExpired) {
axios.refreshingToken = store.dispatch('auth/refreshToken')
await axios.refreshingToken
}
// set authorization header
return config
})