admin管理员组文章数量:1347815
I have setup for axios and react-query together for my food application . I want to implement refreshing token only once for more than 2 parallel request and retry all the pending failed request . I searched so many solutions on the web , tried them but none of them worked . Here is my code reference .
let isRefreshing = false;
let failedQueue = [];
async function refreshToken() {
const response = await normalRoute.post("/users/refresh");
return response.data.accessToken;
}
privateRoute.interceptors.response.use(
(response) => response,
async (error) => {
if (error.response.status === 401) {
failedQueue.push(error.config);
if (!isRefreshing) {
isRefreshing = true;
const token = await refreshToken();
store.dispatch(setAccessToken(token));
const promsieArray = failedQueue.map((config) => {
config.headers.authorization = `Bearer ${token}`;
return privateRoute(config);
});
failedQueue = [];
return Promise.resolve(promsieArray);
}
}
}
);
I have setup for axios and react-query together for my food application . I want to implement refreshing token only once for more than 2 parallel request and retry all the pending failed request . I searched so many solutions on the web , tried them but none of them worked . Here is my code reference .
let isRefreshing = false;
let failedQueue = [];
async function refreshToken() {
const response = await normalRoute.post("/users/refresh");
return response.data.accessToken;
}
privateRoute.interceptors.response.use(
(response) => response,
async (error) => {
if (error.response.status === 401) {
failedQueue.push(error.config);
if (!isRefreshing) {
isRefreshing = true;
const token = await refreshToken();
store.dispatch(setAccessToken(token));
const promsieArray = failedQueue.map((config) => {
config.headers.authorization = `Bearer ${token}`;
return privateRoute(config);
});
failedQueue = [];
return Promise.resolve(promsieArray);
}
}
}
);
Share
Improve this question
asked Apr 6, 2023 at 7:38
DevRohanDevRohan
811 silver badge5 bronze badges
2 Answers
Reset to default 11I think your solution is a little too plicated. I'd simply store the Promise returned by refreshToken()
untill it is fulfilled and let all ining 401
s await the same Promise, then retrying.
let refreshPromise = null;
const clearPromise = () => refreshPromise = null;
async function refreshToken() {
const response = await normalRoute.post("/users/refresh");
return response.data.accessToken;
}
privateRoute.interceptors.response.use(
undefined,
async (error) => {
const config = error.config;
if (error.response.status === 401 && !config._retry) {
config._retry = true;
if (!refreshPromise) {
refreshPromise = refreshToken().finally(clearPromise);
}
const token = await refreshPromise;
config.headers.authorization = `Bearer ${token}`;
return privateRoute(config);
}
}
);
And kill that Promise when it is fulfilled so that later 401
s have a chance to refresh the token yet again.
Thankyou I found solution ..
import { setAccessToken } from "../Store/authSlice";
import store from "../Store";
import { normalRoute } from "./axios";
// for multiple requests
let isRefreshing = false;
let failedQueue = [];
const processQueue = (error, token = null) => {
failedQueue.forEach((prom) => {
if (error) {
prom.reject(error);
} else {
prom.resolve(token);
}
});
failedQueue = [];
};
const interceptor = (axiosInstance) => (error) => {
const _axios = axiosInstance;
const originalRequest = error.config;
if (error.response.status === 401 && !originalRequest._retry) {
if (isRefreshing) {
return new Promise(function (resolve, reject) {
failedQueue.push({ resolve, reject });
})
.then((token) => {
originalRequest.headers["Authorization"] = "Bearer " + token;
return _axios.request(originalRequest);
})
.catch((err) => {
return Promise.reject(err);
});
}
originalRequest._retry = true;
isRefreshing = true;
return new Promise(async (resolve, reject) => {
try {
const response = await normalRoute.post("/users/refresh");
_axios.defaults.headers.mon["Authorization"] =
"Bearer " + response.data.accessToken;
originalRequest.headers["Authorization"] = "Bearer " + response.data.accessToken;
processQueue(null, response.data.accessToken);
resolve(_axios(originalRequest));
} catch (err) {
processQueue(err, null);
reject(err);
} finally {
isRefreshing = false;
}
});
}
return Promise.reject(error);
};
export default interceptor;
import axios from "axios";
import interceptor from "./authInterceptor";
const privateInstance = axios.create({
baseURL: "http://localhost:5000/api/v1",
});
privateInstance.defaults.withCredentials = true;
privateInstance.interceptors.response.use(undefined, interceptor(privateInstance));
export default privateInstance;
本文标签: javascriptHow to run axios interceptor once for multiple request on 401 errorStack Overflow
版权声明:本文标题:javascript - How to run axios interceptor once for multiple request on 401 error? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1743844678a2548900.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论