所以对于axios和上下文来说不是很新,但是我在应用程序级别提供了一个Auth上下文,该上下文由多个子组件使用。在这种情况下,我有一个axios拦截器,它检查对401(未授权)的请求,然后调用刷新令牌api,并将令牌替换为新令牌。我唯一关心的是,第二次调用刷新令牌API时,它会陷入调用刷新令牌api的无尽循环中?任何想法我做错了什么?任何帮助将不胜感激。
AuthContext.js
axios.interceptors.response.use((response) => {
return response
}, function (error) {
const originalRequest = error.config;
if (error.response.status === 401 && originalRequest.url ===
`${BASE_URI}/Identity/Login`) {
history.push('/login');
return Promise.reject(error);
}
if (error.response.status === 401 && !originalRequest._retry) {
originalRequest._retry = true;
const localStorage = JSON.parse(sessionStorage.getItem(AUTH_USER))
const refreshToken = localStorage.refreshToken;
return axios.post(`${BASE_URI}/Identity/Refresh`, null,
{
headers: {
'Refresh-Token': refreshToken
}
})
.then(res => {
if (res.status === 201 || res.status === 200) {
console.log("In refresh request !")
console.log(res)
setSession(null, res.data.token, res.data.refreshToken)
axios.defaults.headers.common['authorization'] = 'Bearer ' + res.data.token;
return axios(originalRequest);
}
}).catch((error) => {
console.log("Inside error refresh")
return Promise.reject(error);
})
}
return Promise.reject(error);
});
答案 0 :(得分:1)
我做了类似的事情,在token过期时获取refresh token,我也遇到了同样的问题,其实你用的是同一个Axios实例,再创建一个实例
const instance = axios.create();
axios.interceptors.request.use(async (config) => {
if (token && refreshToken) {
const data = JSON.parse(atob(token.split('.')[1]));
const time = Math.floor(new Date().getTime() / 1000);
if (data.exp < time) {
instance.defaults.headers.common["Authorization"] = `Bearer ${refreshToken}`;
const { data } = await instance.get(SERVER.API_ROOT + '/tokens/refresh');
if (data?.AccessToken) localStorage.setItem(config.AUTH_TOKEN, data.AccessToken)
else localStorage.clear();
}
return config;
}
希望上面的例子对你有帮助
答案 1 :(得分:0)
嘿,我知道这是一个老问题,但您的问题似乎是使用相同的 axios 实例来请求刷新令牌,实际上是创建了一个嵌套的刷新令牌循环。您可以做的是创建一个新的 axios 实例(与初始实例一起,您将同时使用它们)而无需像这样的拦截器:const noInterceptAxios = axios.create();
,然后使用它来发送不需要的请求检查访问令牌 return noInterceptAxios.post(`/Identity/Refresh).then().catch()
。