From 6d2340070c60ffaf2ed94cb912b10d95d722ec55 Mon Sep 17 00:00:00 2001 From: JunSeong Date: Tue, 25 Feb 2025 18:35:52 +0900 Subject: [PATCH] =?UTF-8?q?FEAT:=20access=20token=20reissue=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/Cabinet/api/axios/axios.instance.ts | 88 +++++++++++++++---- 1 file changed, 72 insertions(+), 16 deletions(-) diff --git a/frontend/src/Cabinet/api/axios/axios.instance.ts b/frontend/src/Cabinet/api/axios/axios.instance.ts index 2642905f4..c058e3770 100644 --- a/frontend/src/Cabinet/api/axios/axios.instance.ts +++ b/frontend/src/Cabinet/api/axios/axios.instance.ts @@ -7,11 +7,51 @@ axios.defaults.withCredentials = true; const instance = axios.create({ baseURL: import.meta.env.VITE_BE_HOST, +}); + +const reissueInstance = axios.create({ + baseURL: import.meta.env.VITE_BE_HOST, withCredentials: true, }); +const reissueToken = async () => { + try { + const token = (() => { + const pathname = window.location.pathname; + if (pathname.startsWith("/admin")) { + return getCookie("admin_access_token"); + } + return getCookie("access_token"); + })(); + + const response = await reissueInstance.post( + "/v5/jwt/reissue", + {}, + { + headers: { + Authorization: `Bearer ${token}`, + }, + } + ); + + if (response.status === 200) { + return true; + } + return false; + } catch (error) { + console.error("Token reissue failed:", error); + return false; + } +}; + instance.interceptors.request.use(async (config) => { - const token = getCookie("admin_access_token") ?? getCookie("access_token"); + const token = (() => { + const pathname = window.location.pathname; + if (pathname.startsWith("/admin")) { + return getCookie("admin_access_token"); + } + return getCookie("access_token"); + })(); config.headers.set("Authorization", `Bearer ${token}`); return config; }); @@ -20,24 +60,40 @@ instance.interceptors.response.use( (response) => { return response; }, - (error) => { - // access_token unauthorized + async (error) => { if (error.response?.status === HttpStatusCode.Unauthorized) { - if (import.meta.env.VITE_IS_LOCAL === "true") { - removeCookie("admin_access_token", { - path: "/", - domain: "localhost", - }); - removeCookie("access_token"); + const isReissued = await reissueToken(); + + if (isReissued) { + const originalRequest = error.config; + + const newToken = window.location.pathname.startsWith("/admin") + ? getCookie("admin_access_token") + : getCookie("access_token"); + + originalRequest.headers.Authorization = `Bearer ${newToken}`; + return instance(originalRequest); } else { - removeCookie("admin_access_token", { - path: "/", - domain: "cabi.42seoul.io", - }); - removeCookie("access_token", { path: "/", domain: "cabi.42seoul.io" }); + const domain = + import.meta.env.VITE_IS_LOCAL === "true" + ? "localhost" + : "cabi.42seoul.io"; + + if (window.location.pathname.startsWith("/admin")) { + removeCookie("admin_access_token", { + path: "/", + domain: domain, + }); + } else { + removeCookie("access_token", { + path: "/", + domain: domain, + }); + } + + window.location.href = "login"; + alert(error.response.data.message); } - window.location.href = "login"; - alert(error.response.data.message); } else if (error.response?.status === HttpStatusCode.InternalServerError) { logAxiosError(error, ErrorType.INTERNAL_SERVER_ERROR, "서버 에러"); }