Refresh token error fix

This commit is contained in:
hamid zarghami
2025-12-29 11:04:31 +03:30
parent e25f6bdeb9
commit cce8d64f25
3 changed files with 82 additions and 5 deletions
+41 -1
View File
@@ -30,6 +30,7 @@ i18next.init({
declare global {
interface Window {
isRefreshingToken?: boolean;
isRefreshTokenExpired?: boolean;
}
}
@@ -37,6 +38,23 @@ const queryClient = new QueryClient({
queryCache: new QueryCache({
onError: async (error: IApiErrorRepsonse) => {
if (error?.response?.status === 401) {
// اگر refresh token منقضی شده باشد، دیگر تلاش نکن
if (window.isRefreshTokenExpired) {
return;
}
// بررسی کن که آیا خطا از refresh endpoint است
const isRefreshEndpoint = error?.config?.url?.includes('/admin/auth/refresh');
// اگر خطا از refresh endpoint است، refresh token منقضی شده
if (isRefreshEndpoint) {
window.isRefreshTokenExpired = true;
await removeToken();
await removeRefreshToken();
window.location.href = Pages.auth.login;
return;
}
try {
// Use a flag to track if refresh is in progress
if (window.isRefreshingToken) {
@@ -57,6 +75,15 @@ const queryClient = new QueryClient({
try {
const refreshTokenValue = await getRefreshToken();
if (!refreshTokenValue) {
window.isRefreshTokenExpired = true;
await removeToken();
await removeRefreshToken();
window.location.href = Pages.auth.login;
return;
}
const { data } = await refreshToken({ refreshToken: refreshTokenValue || '' });
if (data?.accessToken?.token) {
@@ -68,6 +95,9 @@ const queryClient = new QueryClient({
await setRefreshToken(data.refreshToken?.token);
}
// Reset expired flag if refresh was successful
window.isRefreshTokenExpired = false;
// Retry the failed request
queryClient.invalidateQueries();
return;
@@ -79,10 +109,20 @@ const queryClient = new QueryClient({
}
} catch (refreshError: unknown) {
console.error('Token refresh failed:', refreshError);
// بررسی کن که آیا خطا از refresh endpoint است
const errorWithConfig = refreshError as IApiErrorRepsonse;
const isRefreshError = errorWithConfig?.config?.url?.includes('/admin/auth/refresh');
// اگر refresh token خودش 401 خورده، آن را منقضی شده علامت بزن
if (isRefreshError || errorWithConfig?.response?.status === 401) {
window.isRefreshTokenExpired = true;
}
// Clear tokens and redirect to login
await removeToken();
await removeRefreshToken();
// window.location.href = '/auth/login';
window.location.href = Pages.auth.login;
}
}
}
+37 -4
View File
@@ -12,6 +12,7 @@ import { refreshToken } from "../pages/auth/service/AuthService";
declare global {
interface Window {
isRefreshingToken?: boolean;
isRefreshTokenExpired?: boolean;
}
}
@@ -25,6 +26,23 @@ axiosInstance.interceptors.response.use(
const originalRequest = error.config;
if (error?.response?.status === 401 && !originalRequest._retry) {
// اگر refresh token منقضی شده باشد، دیگر تلاش نکن
if (window.isRefreshTokenExpired) {
return Promise.reject(error);
}
// بررسی کن که آیا خطا از refresh endpoint است
const isRefreshEndpoint = originalRequest?.url?.includes('/admin/auth/refresh');
// اگر خطا از refresh endpoint است، refresh token منقضی شده
if (isRefreshEndpoint) {
window.isRefreshTokenExpired = true;
await removeToken();
await removeRefreshToken();
window.location.href = `/`;
return Promise.reject(error);
}
if (window.isRefreshingToken) {
// Wait for the refresh to complete
await new Promise((resolve) => {
@@ -44,10 +62,11 @@ axiosInstance.interceptors.response.use(
try {
const refreshTokenValue = await getRefreshToken();
if (!refreshTokenValue) {
window.isRefreshTokenExpired = true;
await removeRefreshToken();
await removeToken();
window.location.href = `/`;
return;
return Promise.reject(error);
}
const data = await refreshToken({
refreshToken: refreshTokenValue,
@@ -59,19 +78,33 @@ axiosInstance.interceptors.response.use(
await setRefreshToken(data.data.refreshToken.token);
}
// Reset expired flag if refresh was successful
window.isRefreshTokenExpired = false;
originalRequest.headers.Authorization = `Bearer ${data.data.accessToken.token}`;
return axiosInstance(originalRequest);
} else {
window.isRefreshTokenExpired = true;
await removeRefreshToken();
await removeToken();
// window.location.href = `/`;
return;
window.location.href = `/`;
return Promise.reject(error);
}
} catch (refreshError) {
console.error("Token refresh failed:", refreshError);
// بررسی کن که آیا خطا از refresh endpoint است
const isRefreshError = (refreshError as { response?: { config?: { url?: string }; status?: number } })?.response?.config?.url?.includes('/admin/auth/refresh');
const is401Error = (refreshError as { response?: { status?: number } })?.response?.status === 401;
// اگر refresh token خودش 401 خورده، آن را منقضی شده علامت بزن
if (isRefreshError || is401Error) {
window.isRefreshTokenExpired = true;
}
await removeToken();
await removeRefreshToken();
// window.location.href = `/`;
window.location.href = `/`;
return Promise.reject(refreshError);
} finally {
window.isRefreshingToken = false;
+4
View File
@@ -11,4 +11,8 @@ export interface IErrorResponse extends IBaseResponse {
export interface IApiErrorRepsonse extends DefaultError {
response?: IErrorResponse;
config?: {
url?: string;
[key: string]: unknown;
};
}