I am using Axios interceptor to get new Access token with refresh token. The following code creates new access token from server, but I cannot find the cookie in the browser.
Works fine, but the browser struck on loading.
It could be much helpful, if someone can find where the issue is.
Advance thanks.
interface RetryQueueItem {
resolve: (value?: any) => void;
reject: (error?: any) => void;
config: AxiosRequestConfig;
}
const fetchAxiosClient: AxiosInstance = axios.create({
baseURL: 'http://localhost:8080/api/v1',
timeout: 60000
});
fetchAxiosClient.defaults.headers.common = {
'Content-Type': 'application/json',
'Accept': 'application/json'
} as headers;
export async function createAxiosInstance(requestEvent) {
// Auth token to request header
fetchAxiosClient.interceptors.request.use(
(config: InternalAxiosRequestConfig) => {
const token = getAccessToken(requestEvent.cookieObj).access_token;
if (token) {
config.headers['Authorization'] = `Bearer ${token}`;
}
config.headers['Content-Type'] = 'application/json';
return config;
},
error => Promise.reject(error)
);
const refreshAndRetryQueue: RetryQueueItem[] = [];
let isRefreshing = false;
fetchAxiosClient.interceptors.response.use(
function (response: AxiosResponse) {
return response;
},
async function (error: any) {
const originalRequest: AxiosRequestConfig = error.config;
if (error.response && error.response.status === 401) {
if (!isRefreshing) {
isRefreshing = true;
try {
const refreshToken = getRefreshToken(requestEvent.cookieObj);
if (refreshToken) {
await axios.post(
`${fetchAxiosClient?.defaults.baseURL}${REFRESH_TOKEN}`,
{
refresh_token: refreshToken,
}
).then(async (response: any) => {
const cookies = response.headers['set-cookie'] as string[];
const accessToken = getToken(cookies[0], APP_CONSTANTS.ACCESS_TOKEN);
setToken(requestEvent.cookieObj, accessToken!);
return fetchAxiosClient!(originalRequest);
}).catch((error) => {
requestEvent.cookieObj.delete(APP_CONSTANTS.ACCESS_TOKEN, { path: '/' });
throw requestEvent.redirect(302, '/login');
//return Promise.reject(error);
});
refreshAndRetryQueue.forEach(({ config, resolve, reject }) => {
fetchAxiosClient!(config)
.then((response) => resolve(response))
.catch((err) => reject(err));
});
refreshAndRetryQueue.length = 0;
} else {
requestEvent.cookieObj.delete(APP_CONSTANTS.ACCESS_TOKEN, { path: '/' });
window.location.href = "/";
return Promise.reject(error);
}
} catch (refreshError) {
refreshAndRetryQueue.length = 0;
requestEvent.cookieObj.delete(APP_CONSTANTS.ACCESS_TOKEN, { path: '/' });
} finally {
isRefreshing = false;
}
}
return new Promise<void>((resolve, reject) => {
refreshAndRetryQueue.push({ config: originalRequest, resolve, reject });
});
}
return Promise.reject(error);
}
);
}
The new generated access token which will expire in 15 mins should set as cookie. The moment access token expired, new access token should be generated with refresh token.
But, after expiry of access token, while generating new access token the browser shows loading indicator and continuously busy.
2
Answers
I referred this
https://blog.stackademic.com/refresh-access-token-with-axios-interceptors-in-react-js-with-typescript-bd7a2d035562
working fine.
The code logic looks messy. Use this plugin to make your code easier:
https://github.com/Flyrell/axios-auth-refresh