Skip to content

Commit 987d7a4

Browse files
committed
Revert "fix: ticket-admin axios 변경"
This reverts commit b171133.
1 parent 49fa612 commit 987d7a4

7 files changed

Lines changed: 130 additions & 230 deletions

File tree

apps/ticket-admin/src/lib/axios/clientAxios.ts

Lines changed: 0 additions & 122 deletions
This file was deleted.
Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,10 @@
1-
import axios from "axios";
2-
31
import { API_URL } from "@/data/constants";
42

5-
// 엑세스 토큰 재발급 함수
6-
const refreshClient = axios.create({
7-
baseURL: process.env.NEXT_PUBLIC_TICKET_API_BASE_URL,
8-
timeout: 10_000,
9-
headers: {
10-
"Content-Type": "application/json",
11-
},
12-
withCredentials: true,
13-
});
3+
import { instance } from "..";
144

5+
// 엑세스 토큰 재발급 함수
156
export async function refreshAccessToken() {
16-
const { data } = await refreshClient.post(API_URL.USER.REISSUE_ACCESS_TOKEN);
7+
const { data } = await instance.post(API_URL.USER.REISSUE_ACCESS_TOKEN);
178

189
return data;
1910
}
Lines changed: 117 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,119 @@
1-
import { clientAxios } from "./clientAxios";
2-
import { serverAxios } from "./serverAxios";
1+
import axios, { AxiosError, AxiosResponse, InternalAxiosRequestConfig } from "axios";
32

4-
const isServer = typeof window === "undefined";
3+
import { EXTERNAL_PATH } from "@/shared/constants/path";
4+
import { IS_LOGINED } from "@/shared/constants/storage";
5+
import { isAxiosErrorResponse } from "@/shared/types/axioxError";
56

6-
export const instance = isServer ? serverAxios : clientAxios;
7+
import { safeSessionStorage } from "../storage";
8+
import { refreshAccessToken } from "./helpers";
9+
import { ERROR_CODE } from "./utils/errorCode";
10+
11+
export const instance = axios.create({
12+
baseURL: process.env.NEXT_PUBLIC_TICKET_API_BASE_URL,
13+
timeout: 10_000,
14+
headers: {
15+
"Content-Type": "application/json",
16+
},
17+
withCredentials: true,
18+
});
19+
20+
// 요청 인터셉터
21+
instance.interceptors.request.use(
22+
(config: InternalAxiosRequestConfig) => {
23+
return config;
24+
},
25+
(error: AxiosError) => {
26+
return Promise.reject(error);
27+
},
28+
);
29+
30+
let tokenRefreshPromise: Promise<void> | null = null;
31+
let isLoginAlertShown = false;
32+
33+
// 응답 인터셉터
34+
instance.interceptors.response.use(
35+
(response: AxiosResponse) => response?.data,
36+
async (error: AxiosError) => {
37+
if (typeof window === "undefined") {
38+
// Server에서는 기본 전파
39+
console.error(error);
40+
41+
return Promise.reject(error);
42+
}
43+
44+
console.error("##error", JSON.stringify(error));
45+
46+
if (isAxiosErrorResponse(error.response?.data)) {
47+
// 엑세스 토큰 없음
48+
if (
49+
error.response?.data.code === ERROR_CODE.NO_ACCESS_TOKEN ||
50+
error.response?.data.code === ERROR_CODE.REFRESH_TOKEN_EXPIRED
51+
) {
52+
redirectToLoginOnce();
53+
}
54+
55+
if (error?.response?.data.code === ERROR_CODE.NO_ACCESS) {
56+
alert("접근 권한이 필요한 페이지입니다.");
57+
58+
window.location.href = EXTERNAL_PATH.HOME;
59+
}
60+
61+
// 액세스 토큰 만료
62+
if (error.response?.data.code === ERROR_CODE.ACCESS_TOKEN_EXPIRED) {
63+
try {
64+
// 이미 토큰 재발급이 진행 중이면 완료될 때까지 대기
65+
if (tokenRefreshPromise) {
66+
await tokenRefreshPromise;
67+
} else {
68+
// 토큰 재발급 시작
69+
tokenRefreshPromise = refreshAccessToken()
70+
.then(() => {
71+
tokenRefreshPromise = null;
72+
})
73+
.catch((error) => {
74+
tokenRefreshPromise = null;
75+
76+
throw error;
77+
});
78+
}
79+
80+
// 원래 요청 재시도
81+
const originalRequest = error.config;
82+
83+
if (!originalRequest) {
84+
return Promise.reject(error);
85+
}
86+
87+
return instance(originalRequest);
88+
} catch {
89+
if (typeof window !== "undefined") {
90+
redirectToLoginOnce();
91+
92+
return Promise.reject(error?.response?.data);
93+
}
94+
}
95+
}
96+
}
97+
98+
if (error.response?.status === 500) {
99+
return Promise.reject(error?.response?.data);
100+
}
101+
102+
return Promise.reject(error?.response?.data);
103+
},
104+
);
105+
106+
function redirectToLoginOnce() {
107+
if (isLoginAlertShown) return;
108+
109+
isLoginAlertShown = true;
110+
111+
alert("로그인이 필요한 페이지입니다.");
112+
safeSessionStorage.remove(IS_LOGINED);
113+
114+
const redirectUrl = `${EXTERNAL_PATH.LOGIN}?redirectUrl=${encodeURIComponent(
115+
window.location.origin + window.location.pathname + window.location.search,
116+
)}`;
117+
118+
window.location.href = redirectUrl;
119+
}

apps/ticket-admin/src/lib/axios/serverAxios.ts

Lines changed: 0 additions & 56 deletions
This file was deleted.
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
export const ERROR_CODE = {
2+
NO_ACCESS: 40106,
23
LOGIN_REQUIRED: 40402,
34
ACCESS_TOKEN_EXPIRED: 40103,
45
REFRESH_TOKEN_EXPIRED: 40104,
56
NO_ACCESS_TOKEN: 40403,
6-
PAYMENT: 50004,
7+
SERVER_ERROR: 500,
78
} as const;
Lines changed: 7 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,15 @@
1-
import { AxiosError } from "axios";
2-
3-
import { ERROR_CODE } from "@/lib/axios/utils/errorCode";
4-
5-
type ErrorResponse = {
1+
export type AxiosErrorResponse = {
62
code: number;
73
message: string;
84
};
95

10-
export type AxiosErrorResponse = AxiosError<ErrorResponse>;
11-
126
export function isAxiosErrorResponse(error: unknown): error is AxiosErrorResponse {
13-
if (error === null || typeof error !== "object") {
14-
return false;
15-
}
16-
17-
const hasOwnproperty = Object.prototype.hasOwnProperty;
18-
197
return (
20-
hasOwnproperty.call(error, "isAxiosError") ||
21-
(hasOwnproperty.call(error, "config") &&
22-
hasOwnproperty.call(error, "request") &&
23-
hasOwnproperty.call(error, "response"))
8+
typeof error === "object" &&
9+
error !== null &&
10+
"code" in error &&
11+
"message" in error &&
12+
typeof (error as AxiosErrorResponse).code === "number" &&
13+
typeof (error as AxiosErrorResponse).message === "string"
2414
);
2515
}
26-
27-
export function isNotAuthErrorResponse(error: unknown): error is AxiosErrorResponse {
28-
return (
29-
isAxiosErrorResponse(error) &&
30-
(error.response?.data.code === ERROR_CODE.NO_ACCESS_TOKEN ||
31-
error.response?.data.code === ERROR_CODE.REFRESH_TOKEN_EXPIRED)
32-
);
33-
}
34-
35-
export function isAuthError(error: Error): error is AxiosErrorResponse {
36-
return (
37-
isAxiosErrorResponse(error) && error.response?.data.code === ERROR_CODE.ACCESS_TOKEN_EXPIRED
38-
);
39-
}
40-
41-
export function isNetworkError(error: Error): error is AxiosErrorResponse {
42-
return isAxiosErrorResponse(error) && (error.response?.status ?? 0) >= 400;
43-
}

apps/ticket/src/lib/axios/serverAxios.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// lib/axios/server.ts
12
import axios, { AxiosResponse } from "axios";
23

34
export const serverAxios = axios.create({

0 commit comments

Comments
 (0)