I am trying to intercept responses gotten from my node express server using axios interceptors. The goal of this is to spot whenvever i get a 403 error response status as a result of my access token being expired and have my interceptor make a request to my backend to generate a new access token. The interceptor does this by sending a refresh token in form of a cookie which will be validated and checked in the backend as well.
My problem is that since my backend also returns a status code of 403 whenever the refresh token expires, the interceptor keeps making endless request to my server.
Should i just change the status code returned in times of expired refresh tokens?? or is there a way i could stop the endless loop of requests.
Here is my configuration for the interceptor
axios.interceptors.response.use(
(response) => {
return response;
},
async (error) => {
const originalConfig = error.config;
if (error.response) {
if (error.response.status === 403 && !originalConfig?._retry) {
originalConfig._retry = true;
try {
// call refresh token endpoint;
const { data } = await axios.post(
`${import.meta.env.VITE_GENERAL_API_ENDPOINT}auth/generate-token`,
{},
{ withCredentials: true }
);
const { token } = data;
originalConfig.headers.Authorization = `Bearer ${token}`;
axios.defaults.headers.common.Authorization = `Bearer ${token}`;
return axios(originalConfig);
} catch (refreshError) {
console.error("Failed to refresh token:", refreshError);
// Throw an error to stop further execution or handle as appropriate
return Promise.reject(refreshError);
}
}
}
// throw error;
return Promise.reject(error);
}
);
Here is the middleware that checks and validates the refresh token in my node server;
exports.refreshTokenCheck = asyncErrorHandler(async (req, res, next) => {
const refreshToken = req.cookies["refresh_token"];
console.log(refreshToken);
if (!refreshToken) {
console.log(
"we tried generating a new access token but ran into this error because there is no token"
);
return next(new CustomError("Unauthorized", 401));
}
try {
//verify refresh token
const decodedToken = jwt.verify(
refreshToken,
process.env.REFRESH_TOKEN_SECRET_KEY
);
// if (!decodedToken) {
// return next(new CustomError("Unauthorized", 401));
// }
const user = await User.findOne({ _id: decodedToken.id }).populate(
"subscriptions.plan"
);
if (!user) {
return next(new CustomError("User not found", 404));
}
req.user = user;
next();
} catch (error) {
if (
error.name === "TokenExpiredError" ||
error.name === "JsonWebTokenError" ||
error.name === "NotBeforeError"
) {
console.log(
"we tried generating a new access token but ran into this error"
);
return next(new CustomError("Forbidden", 403));
}
next(error);
}
});