[英]Axios - Refresh token loop
所以我對 axios 和上下文相當陌生,但我有一個在應用程序級別提供的身份驗證上下文,並且這個上下文被多個子組件使用。 在這種情況下,我有一個 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);
});
我做了類似的事情來在令牌過期時獲取刷新令牌並且我遇到了同樣的問題,實際上,您使用的是 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;
}
希望上面的例子對你有幫助
嘿,我知道這是一個老問題,但您的問題似乎是使用相同的 axios 實例來請求刷新令牌,本質上是創建一個嵌套的刷新令牌周期。 您可以做的是創建一個新的 axios 實例(與初始實例一起,您將同時使用它們)而不使用這樣的攔截器: const noInterceptAxios = axios.create();
,然后稍后使用它發送不需要檢查訪問令牌的請求, return noInterceptAxios.post(`/Identity/Refresh).then().catch()
。
@J.Naude 我做了類似的事情,但是我為我的一個項目編寫了 axios 的通用包裝器,它處理了幾乎所有的邊緣情況
https://gist.github.com/tapandave/01960228516dd852a49c74d16c0fddb1
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.