From c80b181efb32b688dd3219b5d565023859c1dffe Mon Sep 17 00:00:00 2001 From: jjangminii Date: Tue, 10 Mar 2026 02:45:12 +0900 Subject: [PATCH 1/5] =?UTF-8?q?Fix(client):=20accessToken=20=EB=B0=8F=20re?= =?UTF-8?q?freshToken=20=ED=83=80=EC=9E=85=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?=EB=B0=8F=20=EB=A1=9C=EC=BB=AC=EC=8A=A4=ED=86=A0=EB=A6=AC?= =?UTF-8?q?=EC=A7=80=20=EC=A0=80=EC=9E=A5=20=EB=A1=9C=EC=A7=81=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client/src/pages/onBoarding/GoogleCallback.tsx | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/apps/client/src/pages/onBoarding/GoogleCallback.tsx b/apps/client/src/pages/onBoarding/GoogleCallback.tsx index 1c4c8f1e..9afb3321 100644 --- a/apps/client/src/pages/onBoarding/GoogleCallback.tsx +++ b/apps/client/src/pages/onBoarding/GoogleCallback.tsx @@ -21,7 +21,8 @@ const GoogleCallback = () => { const handleUserLogin = ( isUser: boolean, - accessToken: string | undefined, + accessToken: string | null, + refreshToken: string | null, hasJob?: boolean ) => { if (isUser) { @@ -39,6 +40,11 @@ const GoogleCallback = () => { }; sendTokenToExtension(accessToken); } + + if (refreshToken) { + localStorage.setItem('refreshToken', refreshToken); + } + if (typeof hasJob === 'boolean') { localStorage.setItem('hasJob', String(hasJob)); } @@ -58,12 +64,14 @@ const GoogleCallback = () => { code, uri: redirectUri, }); - const { isUser, userId, email, accessToken, hasJob } = res.data.data; + + const { isUser, userId, email, accessToken, refreshToken, hasJob } = + res.data.data; localStorage.setItem('email', email); localStorage.setItem('userId', userId); - handleUserLogin(isUser, accessToken, hasJob); + handleUserLogin(isUser, accessToken, refreshToken, hasJob); } catch (error) { console.error('로그인 오류:', error); navigate('/onboarding?step=SOCIAL_LOGIN'); From 2effd3858c6fb5d44d6a953ffa2e87a90c03c181 Mon Sep 17 00:00:00 2001 From: jjangminii Date: Tue, 10 Mar 2026 14:43:18 +0900 Subject: [PATCH 2/5] =?UTF-8?q?Fix(client):=20loginWithCode=20=ED=95=A8?= =?UTF-8?q?=EC=88=98=EC=97=90=EC=84=9C=20apiRequest.post=20=ED=98=B8?= =?UTF-8?q?=EC=B6=9C=20=ED=98=95=EC=8B=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client/src/pages/onBoarding/GoogleCallback.tsx | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/apps/client/src/pages/onBoarding/GoogleCallback.tsx b/apps/client/src/pages/onBoarding/GoogleCallback.tsx index 9afb3321..e7e19c24 100644 --- a/apps/client/src/pages/onBoarding/GoogleCallback.tsx +++ b/apps/client/src/pages/onBoarding/GoogleCallback.tsx @@ -60,10 +60,16 @@ const GoogleCallback = () => { const loginWithCode = async (code: string) => { try { - const res = await apiRequest.post('/api/v3/auth/google', { - code, - uri: redirectUri, - }); + const res = await apiRequest.post( + '/api/v3/auth/google', + { + code, + uri: redirectUri, + }, + { + withCredentials: true, // 👈 이거 필수!! + } + ); const { isUser, userId, email, accessToken, refreshToken, hasJob } = res.data.data; From e22c16007bf7007161f7ac1c93d3632ec0352fd4 Mon Sep 17 00:00:00 2001 From: jjangminii Date: Tue, 10 Mar 2026 14:43:24 +0900 Subject: [PATCH 3/5] =?UTF-8?q?Fix(client):=20apiRequest=20=EC=9D=91?= =?UTF-8?q?=EB=8B=B5=20=EC=9D=B8=ED=84=B0=EC=85=89=ED=84=B0=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EA=B5=AC=EA=B8=80=20=EC=9D=B8=EC=A6=9D=20=EB=B0=8F?= =?UTF-8?q?=20=ED=86=A0=ED=81=B0=20=EC=9E=AC=EB=B0=9C=EA=B8=89=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/shared/apis/setting/axiosInstance.ts | 33 ++++++++++++++++--- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/apps/client/src/shared/apis/setting/axiosInstance.ts b/apps/client/src/shared/apis/setting/axiosInstance.ts index a23bedf4..b79cabb4 100644 --- a/apps/client/src/shared/apis/setting/axiosInstance.ts +++ b/apps/client/src/shared/apis/setting/axiosInstance.ts @@ -28,7 +28,8 @@ apiRequest.interceptors.response.use( const noAuthNeeded = [ '/api/v1/auth/token', '/api/v3/auth/signup', - '/api/v2/auth/google', + '/api/v3/auth/google', + '/api/v3/auth/reissue', ]; const isNoAuth = noAuthNeeded.some((url) => @@ -46,10 +47,34 @@ apiRequest.interceptors.response.use( ) { originalRequest._retry = true; - // localStorage.removeItem('token'); - window.location.href = '/onboarding?step=SOCIAL_LOGIN'; + try { + const res = await axios.post( + `${import.meta.env.VITE_BASE_URL}/api/v3/auth/reissue`, + {}, + { + withCredentials: true, + } + ); - return Promise.reject(error); + const newAccessToken = res.data.data.token; + localStorage.setItem('token', newAccessToken); + + window.postMessage( + { type: 'SET_TOKEN', token: newAccessToken }, + window.location.origin + ); + + originalRequest.headers.Authorization = `Bearer ${newAccessToken}`; + return apiRequest(originalRequest); + } catch (reissueError) { + console.error('토큰 재발급 실패. 다시 로그인해주세요.', reissueError); + + localStorage.removeItem('token'); + localStorage.removeItem('refreshToken'); + window.location.href = '/onboarding?step=SOCIAL_LOGIN'; + + return Promise.reject(reissueError); + } } return Promise.reject(error); From 3e0bbff81de26d30eded33ea289d72e5d647213a Mon Sep 17 00:00:00 2001 From: jjangminii Date: Tue, 10 Mar 2026 16:04:55 +0900 Subject: [PATCH 4/5] =?UTF-8?q?chore:=20=EC=A3=BC=EC=84=9D=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/client/src/pages/onBoarding/GoogleCallback.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/client/src/pages/onBoarding/GoogleCallback.tsx b/apps/client/src/pages/onBoarding/GoogleCallback.tsx index e7e19c24..adf568ad 100644 --- a/apps/client/src/pages/onBoarding/GoogleCallback.tsx +++ b/apps/client/src/pages/onBoarding/GoogleCallback.tsx @@ -67,7 +67,7 @@ const GoogleCallback = () => { uri: redirectUri, }, { - withCredentials: true, // 👈 이거 필수!! + withCredentials: true, } ); From def11bbd73c07db85be2b8d3090a86662b51e62f Mon Sep 17 00:00:00 2001 From: jjangminii Date: Tue, 10 Mar 2026 16:11:39 +0900 Subject: [PATCH 5/5] =?UTF-8?q?Refactor(client):=20sendTokenToExtension=20?= =?UTF-8?q?=ED=95=A8=EC=88=98=EB=A5=BC=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20=EC=99=B8=EB=B6=80=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/pages/onBoarding/GoogleCallback.tsx | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/apps/client/src/pages/onBoarding/GoogleCallback.tsx b/apps/client/src/pages/onBoarding/GoogleCallback.tsx index adf568ad..0a872de4 100644 --- a/apps/client/src/pages/onBoarding/GoogleCallback.tsx +++ b/apps/client/src/pages/onBoarding/GoogleCallback.tsx @@ -3,6 +3,16 @@ import LoadingChippi from '@shared/components/loadingChippi/LoadingChippi'; import { useEffect } from 'react'; import { useNavigate, useSearchParams } from 'react-router-dom'; +const sendTokenToExtension = (token: string) => { + window.postMessage( + { + type: 'SET_TOKEN', + token, + }, + window.location.origin + ); +}; + const GoogleCallback = () => { const navigate = useNavigate(); const [searchParams] = useSearchParams(); @@ -28,16 +38,6 @@ const GoogleCallback = () => { if (isUser) { if (accessToken) { localStorage.setItem('token', accessToken); - - const sendTokenToExtension = (token: string) => { - window.postMessage( - { - type: 'SET_TOKEN', - token, - }, - window.location.origin - ); - }; sendTokenToExtension(accessToken); }