-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathaxios.ts
105 lines (91 loc) · 3.16 KB
/
axios.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import axios, { type AxiosRequestConfig } from 'axios';
import { useAuthStore } from '../stores/auth';
interface RetryAxiosRequestConfig extends AxiosRequestConfig {
_retry?: boolean;
}
interface FailedRequestQueueItem {
config: AxiosRequestConfig;
resolve: (token: string) => void;
reject: (reason?: any) => void;
}
let isRefreshing = false;
let failedQueue: FailedRequestQueueItem[] = [];
const processQueue = (error: string | null, token: string | null) => {
failedQueue.forEach((prom) => {
if (!prom.config.headers) {
prom.config.headers = {};
}
if (error) {
prom.reject(new Error(error));
} else if (token) {
prom.config.headers['Authorization'] = `Bearer ${token}`;
prom.resolve(token);
}
});
failedQueue = [];
};
export function configureAxios() {
const baseURL = import.meta.env.VITE_REMOTE_API;
axios.defaults.baseURL = baseURL;
axios.defaults.headers['Content-Type'] = 'application/json';
axios.interceptors.request.use((config) => {
const token = localStorage.getItem('token');
if (token) {
config.headers['Authorization'] = `Bearer ${token}`;
}
return config;
}, (error) => {
return Promise.reject(error);
});
axios.interceptors.response.use((response) => {
return response;
}, async (error) => {
const originalRequest = error.config as RetryAxiosRequestConfig;
if (error.response.status === 401 && !originalRequest._retry) {
if (isRefreshing) {
return new Promise((resolve, reject) => {
failedQueue.push({
config: originalRequest,
resolve: (newToken: string) => {
originalRequest.headers = originalRequest.headers || {};
originalRequest.headers['Authorization'] = 'Bearer ' + newToken;
resolve(axios(originalRequest));
},
reject
});
});
}
originalRequest._retry = true;
isRefreshing = true;
const refreshToken = localStorage.getItem('refreshToken');
return new Promise<void>((resolve, reject) => {
axios.post(`${baseURL}/refresh-token`, { refreshToken }, {
headers: {
'Content-Type': 'application/json',
},
}).then(({ data }) => {
const authStore = useAuthStore();
if (data.token && refreshToken) {
authStore.setTokens(data.token, refreshToken);
localStorage.setItem('token', data.token);
axios.defaults.headers['Authorization'] = `Bearer ${data.token}`;
processQueue(null, data.token);
resolve();
} else {
processQueue('Access token or refresh token is missing', null);
authStore.logout();
reject(new Error('Access token or refresh token is missing'));
}
}).catch(refreshError => {
const errorMessage = refreshError instanceof Error ? refreshError.message : String(refreshError);
processQueue(errorMessage, null);
const authStore = useAuthStore();
authStore.logout();
}).finally(() => {
isRefreshing = false;
});
});
}
return Promise.reject(error);
});
}