-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinstance.ts
More file actions
76 lines (59 loc) · 2.1 KB
/
Copy pathinstance.ts
File metadata and controls
76 lines (59 loc) · 2.1 KB
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
import axios from "axios";
import { PATH } from "@/routes/paths";
import { useAuthStore } from "@/stores/useAuthStore";
import type { ApiResponse } from "@/types/api";
import type { AuthTokenResponse } from "@/types/auth/auth";
const BASE_CONFIG = {
baseURL: `${import.meta.env.VITE_API_BASE_URL}/api/v1`,
headers: { "Content-Type": "application/json" },
timeout: 10000,
};
// 토큰이 필요 없는 요청 — 로그인, 회원가입, 토큰 재발급
export const publicInstance = axios.create(BASE_CONFIG);
// 토큰이 필요한 요청 — 헤더 자동 첨부, 401이면 재발급 후 재시도
export const authInstance = axios.create(BASE_CONFIG);
authInstance.interceptors.request.use((config) => {
const { accessToken } = useAuthStore.getState();
if (accessToken) {
config.headers.Authorization = `Bearer ${accessToken}`;
}
return config;
});
let reissuePromise: Promise<string> | null = null;
const reissueAccessToken = async () => {
const { refreshToken } = useAuthStore.getState();
if (!refreshToken) return null;
reissuePromise ??= publicInstance
.post<ApiResponse<AuthTokenResponse>>("/auth/reissue", { refreshToken })
.then((response) => {
const tokens = response.data.data;
useAuthStore.getState().setTokens(tokens);
return tokens.accessToken;
})
.finally(() => {
reissuePromise = null;
});
return reissuePromise.catch(() => null);
};
authInstance.interceptors.response.use(
(response) => response,
async (error) => {
const status = error.response?.status;
const originRequest = error.config;
if (status === 401 && originRequest) {
if (!originRequest.isRetried) {
originRequest.isRetried = true;
const accessToken = await reissueAccessToken();
if (accessToken) {
originRequest.headers.Authorization = `Bearer ${accessToken}`;
return authInstance(originRequest);
}
}
useAuthStore.getState().clearAuth();
if (window.location.pathname !== PATH.LOGIN) {
window.location.replace(PATH.LOGIN);
}
}
return Promise.reject(error);
}
);