用于刷新令牌的Axios响应拦截器不断启动



逻辑:在每个请求上都有一个JWT授权头,用于验证用户。如果过期,就会有一个cookie端点准备刷新JWT。

我正在使用axios拦截器响应来检查客户端是否获得401以尝试刷新JWT。cookie可能有效,也可能无效。

问题是,刷新JWT的拦截器从未停止启动,我认为我在同步请求方面有问题。以下是我的代码:

function refreshToken(dispatch) {
return new Promise((resolve, reject) => {
instance.put('/auth').then((response) => {
dispatch({ type: "UPDATE_AUTH", payload: response.data });
resolve(response);
})
.catch((error) => {
reject(error);
});
});
}
instance.interceptors.response.use(
response => {
return response;
},
err => {
const error = err.response;

if (error.status === 401 && error.config && !error.config._retry) {
error.config._retry = true;
return refreshToken(dispatch).then((resp) => {
return instance(error.config);
})
.catch((e) => {
return Promise.reject(e);
});
}
return Promise.reject(error);
}
);

如果您有多个并行请求,刷新JWT将等于请求数。尝试仅第一次发送/auth,并阻止下一次请求。您可以将localStorage用于此任务。

let requests = [];
instance.interceptors.response.use(
response => {
return response;
},
err => {
const error = err.response;

if (error.status === 401 && error.config && !error.config._retry) {
requests.push(error.config);
if (!localStorage.getItem('refresh')) {
localStorage.setItem('refresh', 'done');
error.config._retry = true;
return refreshToken(dispatch).then((resp) => {
localStorage.removeItem('refresh');

const token = getAccessToken();
requests.map(req => {
req.headers.Authorization = `Bearer ${token}`;
return instance(req)
})
})
.catch((e) => {
localStorage.removeItem('refresh');
return Promise.reject(e);
});
}
} else {
requests = [];
}
return Promise.reject(error);
}
);

最新更新