From 7c9c7444d2700ab06abcf1eb6d8cda1590a87cc2 Mon Sep 17 00:00:00 2001 From: constantly-dev Date: Tue, 10 Mar 2026 21:04:43 +0900 Subject: [PATCH 1/8] =?UTF-8?q?refactor:=20reissueToken=20fetch=20function?= =?UTF-8?q?=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/shared/apis/setting/axiosInstance.ts | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/apps/client/src/shared/apis/setting/axiosInstance.ts b/apps/client/src/shared/apis/setting/axiosInstance.ts index b79cabb..8f69b56 100644 --- a/apps/client/src/shared/apis/setting/axiosInstance.ts +++ b/apps/client/src/shared/apis/setting/axiosInstance.ts @@ -8,6 +8,16 @@ const apiRequest = axios.create({ }, }); +const reissueToken = async () => { + return await axios.post( + `${import.meta.env.VITE_BASE_URL}/api/v3/auth/reissue`, + {}, + { + withCredentials: true, + } + ); +}; + // 요청 인터셉터 apiRequest.interceptors.request.use(async (config) => { const token = localStorage.getItem('token'); @@ -48,13 +58,7 @@ apiRequest.interceptors.response.use( originalRequest._retry = true; try { - const res = await axios.post( - `${import.meta.env.VITE_BASE_URL}/api/v3/auth/reissue`, - {}, - { - withCredentials: true, - } - ); + const res = await reissueToken(); const newAccessToken = res.data.data.token; localStorage.setItem('token', newAccessToken); From 85480f6078e56912f89ba5b38c0ac82005ba1937 Mon Sep 17 00:00:00 2001 From: constantly-dev Date: Tue, 10 Mar 2026 21:08:19 +0900 Subject: [PATCH 2/8] =?UTF-8?q?refactor:=20noAuthNeeded=20=EB=B0=B0?= =?UTF-8?q?=EC=97=B4=20=EC=84=A0=EC=96=B8=EB=B6=80=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/shared/apis/setting/axiosInstance.ts | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/apps/client/src/shared/apis/setting/axiosInstance.ts b/apps/client/src/shared/apis/setting/axiosInstance.ts index 8f69b56..39de73a 100644 --- a/apps/client/src/shared/apis/setting/axiosInstance.ts +++ b/apps/client/src/shared/apis/setting/axiosInstance.ts @@ -1,12 +1,11 @@ import axios from 'axios'; -// Axios 인스턴스 -const apiRequest = axios.create({ - baseURL: import.meta.env.VITE_BASE_URL, - headers: { - 'Content-Type': 'application/json', - }, -}); +const noAuthNeeded = [ + '/api/v1/auth/token', + '/api/v3/auth/signup', + '/api/v3/auth/google', + '/api/v3/auth/reissue', +]; const reissueToken = async () => { return await axios.post( @@ -18,6 +17,14 @@ const reissueToken = async () => { ); }; +// Axios 인스턴스 +const apiRequest = axios.create({ + baseURL: import.meta.env.VITE_BASE_URL, + headers: { + 'Content-Type': 'application/json', + }, +}); + // 요청 인터셉터 apiRequest.interceptors.request.use(async (config) => { const token = localStorage.getItem('token'); @@ -35,13 +42,6 @@ apiRequest.interceptors.response.use( async (error) => { const originalRequest = error.config; - const noAuthNeeded = [ - '/api/v1/auth/token', - '/api/v3/auth/signup', - '/api/v3/auth/google', - '/api/v3/auth/reissue', - ]; - const isNoAuth = noAuthNeeded.some((url) => originalRequest.url?.includes(url) ); From f943cc0bce9a2a2ee14c565b9cf064150ce76c30 Mon Sep 17 00:00:00 2001 From: constantly-dev Date: Tue, 10 Mar 2026 21:31:06 +0900 Subject: [PATCH 3/8] =?UTF-8?q?refactor:=20syncAccessToken=20&=20clearAuth?= =?UTF-8?q?SessionAndRedirect=20function=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/shared/apis/setting/axiosInstance.ts | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/apps/client/src/shared/apis/setting/axiosInstance.ts b/apps/client/src/shared/apis/setting/axiosInstance.ts index 39de73a..42ebd68 100644 --- a/apps/client/src/shared/apis/setting/axiosInstance.ts +++ b/apps/client/src/shared/apis/setting/axiosInstance.ts @@ -17,6 +17,21 @@ const reissueToken = async () => { ); }; +const syncAccessToken = (token: string) => { + localStorage.setItem('token', token); + + window.postMessage( + { type: 'SET_TOKEN', token }, + window.location.origin + ); +}; + +const clearAuthSessionAndRedirect = () => { + localStorage.removeItem('token'); + localStorage.removeItem('refreshToken'); + window.location.href = '/onboarding?step=SOCIAL_LOGIN'; +}; + // Axios 인스턴스 const apiRequest = axios.create({ baseURL: import.meta.env.VITE_BASE_URL, @@ -59,23 +74,20 @@ apiRequest.interceptors.response.use( try { const res = await reissueToken(); + const newAccessToken = res.data?.data?.token; - const newAccessToken = res.data.data.token; - localStorage.setItem('token', newAccessToken); - - window.postMessage( - { type: 'SET_TOKEN', token: newAccessToken }, - window.location.origin - ); + if (!newAccessToken) { + throw new Error('토큰 재발급 응답에 access token이 없습니다.'); + } + syncAccessToken(newAccessToken); + originalRequest.headers = originalRequest.headers ?? {}; 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'; + clearAuthSessionAndRedirect(); return Promise.reject(reissueError); } From c0a99b7cb357431ce9d55cb6eb97356e1e3623b3 Mon Sep 17 00:00:00 2001 From: constantly-dev Date: Tue, 10 Mar 2026 22:50:24 +0900 Subject: [PATCH 4/8] =?UTF-8?q?refactor:=20add=20packages=20contracts=20(e?= =?UTF-8?q?xtension-client=20=ED=86=B5=EC=8B=A0/=EA=B3=84=EC=95=BD?= =?UTF-8?q?=EC=9A=A9=20=EA=B3=B5=ED=86=B5=20=EC=83=81=EC=88=98=20&=20?= =?UTF-8?q?=ED=83=80=EC=9E=85)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/client/package.json | 1 + apps/extension/package.json | 1 + packages/contracts/package.json | 16 ++++++++++++++++ packages/contracts/src/extension-messages.ts | 16 ++++++++++++++++ packages/contracts/tsconfig.json | 10 ++++++++++ pnpm-lock.yaml | 15 +++++++++++++++ 6 files changed, 59 insertions(+) create mode 100644 packages/contracts/package.json create mode 100644 packages/contracts/src/extension-messages.ts create mode 100644 packages/contracts/tsconfig.json diff --git a/apps/client/package.json b/apps/client/package.json index ba5b869..6055c74 100644 --- a/apps/client/package.json +++ b/apps/client/package.json @@ -10,6 +10,7 @@ "preview": "vite preview" }, "dependencies": { + "@pinback/contracts": "workspace:*", "@tanstack/react-query": "^5.85.3", "axios": "^1.11.0", "class-variance-authority": "^0.7.1", diff --git a/apps/extension/package.json b/apps/extension/package.json index 34a444b..f1f7715 100644 --- a/apps/extension/package.json +++ b/apps/extension/package.json @@ -11,6 +11,7 @@ "zip": "vite build && node scripts/zip.mjs" }, "dependencies": { + "@pinback/contracts": "workspace:*", "@tanstack/react-query": "^5.85.5", "axios": "^1.11.0", "react": "^19.1.1", diff --git a/packages/contracts/package.json b/packages/contracts/package.json new file mode 100644 index 0000000..8f66219 --- /dev/null +++ b/packages/contracts/package.json @@ -0,0 +1,16 @@ +{ + "name": "@pinback/contracts", + "version": "0.0.0", + "private": true, + "type": "module", + "exports": { + "./extension-messages": "./src/extension-messages.ts" + }, + "scripts": { + "check-types": "tsc --noEmit" + }, + "devDependencies": { + "@pinback/typescript-config": "workspace:*", + "typescript": "5.9.2" + } +} diff --git a/packages/contracts/src/extension-messages.ts b/packages/contracts/src/extension-messages.ts new file mode 100644 index 0000000..ef9ef2a --- /dev/null +++ b/packages/contracts/src/extension-messages.ts @@ -0,0 +1,16 @@ +export const EXTENSION_MESSAGE_TYPE = { + setToken: 'SET_TOKEN', + logout: 'Extension-Logout', +} as const; + +export type ExtensionMessageType = + (typeof EXTENSION_MESSAGE_TYPE)[keyof typeof EXTENSION_MESSAGE_TYPE]; + +export type ExtensionMessage = + | { + type: typeof EXTENSION_MESSAGE_TYPE.setToken; + token: string; + } + | { + type: typeof EXTENSION_MESSAGE_TYPE.logout; + }; diff --git a/packages/contracts/tsconfig.json b/packages/contracts/tsconfig.json new file mode 100644 index 0000000..9fa8bc1 --- /dev/null +++ b/packages/contracts/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../typescript-config/base.json", + "compilerOptions": { + "rootDir": ".", + "baseUrl": ".", + "lib": ["ES2022"] + }, + "include": ["src"], + "exclude": ["node_modules", "dist"] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fe006cc..205b399 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -90,6 +90,9 @@ importers: apps/client: dependencies: + '@pinback/contracts': + specifier: workspace:* + version: link:../../packages/contracts '@tanstack/react-query': specifier: ^5.85.3 version: 5.85.5(react@19.1.1) @@ -184,6 +187,9 @@ importers: apps/extension: dependencies: + '@pinback/contracts': + specifier: workspace:* + version: link:../../packages/contracts '@tanstack/react-query': specifier: ^5.85.5 version: 5.85.5(react@19.1.1) @@ -346,6 +352,15 @@ importers: specifier: ^5.1.4 version: 5.1.4(typescript@5.8.3)(vite@7.1.2(@types/node@22.15.3)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.20.4)(yaml@2.8.1)) + packages/contracts: + devDependencies: + '@pinback/typescript-config': + specifier: workspace:* + version: link:../typescript-config + typescript: + specifier: 5.9.2 + version: 5.9.2 + packages/design-system: dependencies: '@ncdai/react-wheel-picker': From 04d82e2a2fffd4fa2fcaa7aa698bbc3079672ad9 Mon Sep 17 00:00:00 2001 From: constantly-dev Date: Tue, 10 Mar 2026 22:52:03 +0900 Subject: [PATCH 5/8] =?UTF-8?q?refactor:=20client=20authStorage=20?= =?UTF-8?q?=EC=B6=94=EC=83=81=ED=99=94=20=EC=9C=A0=ED=8B=B8=20=ED=95=A8?= =?UTF-8?q?=EC=88=98=20=EA=B0=9D=EC=B2=B4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/client/src/shared/utils/authStorage.ts | 27 +++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 apps/client/src/shared/utils/authStorage.ts diff --git a/apps/client/src/shared/utils/authStorage.ts b/apps/client/src/shared/utils/authStorage.ts new file mode 100644 index 0000000..1ffafc6 --- /dev/null +++ b/apps/client/src/shared/utils/authStorage.ts @@ -0,0 +1,27 @@ +const AUTH_STORAGE_KEYS = { + token: 'token', + refreshToken: 'refreshToken', + email: 'email', + userId: 'userId', + hasJob: 'hasJob', +} as const; + +export const authStorage = { + getAccessToken: () => localStorage.getItem(AUTH_STORAGE_KEYS.token), + hasAccessToken: () => !!localStorage.getItem(AUTH_STORAGE_KEYS.token), + setAccessToken: (token: string) => + localStorage.setItem(AUTH_STORAGE_KEYS.token, token), + setRefreshToken: (refreshToken: string) => + localStorage.setItem(AUTH_STORAGE_KEYS.refreshToken, refreshToken), + setHasJob: (hasJob: boolean) => + localStorage.setItem(AUTH_STORAGE_KEYS.hasJob, String(hasJob)), + setUserIdentity: (email: string, userId: string) => { + localStorage.setItem(AUTH_STORAGE_KEYS.email, email); + localStorage.setItem(AUTH_STORAGE_KEYS.userId, userId); + }, + clearSession: () => { + Object.values(AUTH_STORAGE_KEYS).forEach((key) => { + localStorage.removeItem(key); + }); + }, +}; From 822393ebbf181bb0dd694c42bf68ca8b9a02705a Mon Sep 17 00:00:00 2001 From: constantly-dev Date: Tue, 10 Mar 2026 22:52:58 +0900 Subject: [PATCH 6/8] =?UTF-8?q?refactor:=20extension=20message=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20extensionBridge=EC=97=90=20function=20=EC=B6=94?= =?UTF-8?q?=EC=83=81=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/shared/utils/extensionBridge.ts | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 apps/client/src/shared/utils/extensionBridge.ts diff --git a/apps/client/src/shared/utils/extensionBridge.ts b/apps/client/src/shared/utils/extensionBridge.ts new file mode 100644 index 0000000..fb5f74a --- /dev/null +++ b/apps/client/src/shared/utils/extensionBridge.ts @@ -0,0 +1,21 @@ +import { EXTENSION_MESSAGE_TYPE } from '@pinback/contracts/extension-messages'; + +export const extensionBridge = { + syncToken: (token: string) => { + window.postMessage( + { + type: EXTENSION_MESSAGE_TYPE.setToken, + token, + }, + window.location.origin + ); + }, + logout: () => { + window.postMessage( + { + type: EXTENSION_MESSAGE_TYPE.logout, + }, + window.location.origin + ); + }, +}; From 4ccead2bf49663f966cb373c3e3394e4c0472bc4 Mon Sep 17 00:00:00 2001 From: constantly-dev Date: Tue, 10 Mar 2026 22:53:41 +0900 Subject: [PATCH 7/8] =?UTF-8?q?refactor:=20extension=20EXTENSION=5FMESSAGE?= =?UTF-8?q?=5FTYPE=20=EC=82=AC=EC=9A=A9=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/extension/src/background.ts | 6 ++++-- apps/extension/src/content.ts | 8 +++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/apps/extension/src/background.ts b/apps/extension/src/background.ts index 16530b8..42b17fc 100644 --- a/apps/extension/src/background.ts +++ b/apps/extension/src/background.ts @@ -1,3 +1,5 @@ +import { EXTENSION_MESSAGE_TYPE } from '@pinback/contracts/extension-messages'; + chrome.runtime.onInstalled.addListener((details) => { if (details.reason === 'install') { chrome.identity.getProfileUserInfo(function (info) { @@ -14,7 +16,7 @@ chrome.runtime.onInstalled.addListener((details) => { }); chrome.runtime.onMessage.addListener((message) => { - if (message.type === 'SET_TOKEN') { + if (message.type === EXTENSION_MESSAGE_TYPE.setToken) { chrome.storage.local.set({ token: message.token }, () => { console.log('Token saved!'); }); @@ -22,7 +24,7 @@ chrome.runtime.onMessage.addListener((message) => { }); chrome.runtime.onMessage.addListener((message) => { - if (message.type === 'Extension-Logout') { + if (message.type === EXTENSION_MESSAGE_TYPE.logout) { chrome.storage.local.remove('token', () => { console.log('Token removed!'); }); diff --git a/apps/extension/src/content.ts b/apps/extension/src/content.ts index 490c2e3..92002d6 100644 --- a/apps/extension/src/content.ts +++ b/apps/extension/src/content.ts @@ -1,8 +1,10 @@ +import { EXTENSION_MESSAGE_TYPE } from '@pinback/contracts/extension-messages'; + window.addEventListener('message', (event) => { if (event.source !== window) return; - if (event.data.type === 'SET_TOKEN') { + if (event.data.type === EXTENSION_MESSAGE_TYPE.setToken) { chrome.runtime.sendMessage({ - type: 'SET_TOKEN', + type: EXTENSION_MESSAGE_TYPE.setToken, token: event.data.token, }); chrome.storage.local.set({ token: event.data.token }, () => { @@ -13,7 +15,7 @@ window.addEventListener('message', (event) => { window.addEventListener('message', (event) => { if (event.source !== window) return; - if (event.data.type === 'Extension-Logout') { + if (event.data.type === EXTENSION_MESSAGE_TYPE.logout) { chrome.storage.local.remove('token', () => { console.log('Token removed!'); }); From 6ddda83f38c2c518026bde5d4f2c20f8dacd3a9e Mon Sep 17 00:00:00 2001 From: constantly-dev Date: Tue, 10 Mar 2026 22:54:32 +0900 Subject: [PATCH 8/8] =?UTF-8?q?refactor:=20apps/client=20authStorage=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/client/src/layout/Layout.tsx | 3 ++- .../src/pages/onBoarding/GoogleCallback.tsx | 23 ++++++------------- apps/client/src/shared/apis/queries.ts | 15 ++++-------- .../src/shared/apis/setting/axiosInstance.ts | 16 ++++++------- .../components/profilePopup/ProfilePopup.tsx | 16 ++++--------- 5 files changed, 24 insertions(+), 49 deletions(-) diff --git a/apps/client/src/layout/Layout.tsx b/apps/client/src/layout/Layout.tsx index bab2469..cb50925 100644 --- a/apps/client/src/layout/Layout.tsx +++ b/apps/client/src/layout/Layout.tsx @@ -2,6 +2,7 @@ import { ROUTES_CONFIG } from '@routes/routesConfig'; import { useGetHasJob } from '@shared/apis/queries'; import JobSelectionFunnel from '@shared/components/jobSelectionFunnel/JobSelectionFunnel'; import { Sidebar } from '@shared/components/sidebar/Sidebar'; +import { authStorage } from '@shared/utils/authStorage'; import { useQueryClient } from '@tanstack/react-query'; import { Outlet, useLocation } from 'react-router-dom'; @@ -19,7 +20,7 @@ const Layout = () => { location.pathname.startsWith(ROUTES_CONFIG.onboardingCallback.path); const isSidebarHidden = isAuthPage || isPolicyPage; - const isLoggedIn = !!localStorage.getItem('token'); + const isLoggedIn = authStorage.hasAccessToken(); const { data: hasJobData, isLoading: isHasJobLoading } = useGetHasJob( isLoggedIn && !isAuthPage diff --git a/apps/client/src/pages/onBoarding/GoogleCallback.tsx b/apps/client/src/pages/onBoarding/GoogleCallback.tsx index 0a872de..a742e7f 100644 --- a/apps/client/src/pages/onBoarding/GoogleCallback.tsx +++ b/apps/client/src/pages/onBoarding/GoogleCallback.tsx @@ -1,18 +1,10 @@ import apiRequest from '@shared/apis/setting/axiosInstance'; import LoadingChippi from '@shared/components/loadingChippi/LoadingChippi'; +import { authStorage } from '@shared/utils/authStorage'; +import { extensionBridge } from '@shared/utils/extensionBridge'; 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(); @@ -37,16 +29,16 @@ const GoogleCallback = () => { ) => { if (isUser) { if (accessToken) { - localStorage.setItem('token', accessToken); - sendTokenToExtension(accessToken); + authStorage.setAccessToken(accessToken); + extensionBridge.syncToken(accessToken); } if (refreshToken) { - localStorage.setItem('refreshToken', refreshToken); + authStorage.setRefreshToken(refreshToken); } if (typeof hasJob === 'boolean') { - localStorage.setItem('hasJob', String(hasJob)); + authStorage.setHasJob(hasJob); } navigate('/'); } else { @@ -74,8 +66,7 @@ const GoogleCallback = () => { const { isUser, userId, email, accessToken, refreshToken, hasJob } = res.data.data; - localStorage.setItem('email', email); - localStorage.setItem('userId', userId); + authStorage.setUserIdentity(email, userId); handleUserLogin(isUser, accessToken, refreshToken, hasJob); } catch (error) { diff --git a/apps/client/src/shared/apis/queries.ts b/apps/client/src/shared/apis/queries.ts index 7e2a37b..e4e1d2b 100644 --- a/apps/client/src/shared/apis/queries.ts +++ b/apps/client/src/shared/apis/queries.ts @@ -29,6 +29,8 @@ import { JobsResponse, } from '@shared/types/api'; import { fetchOGData } from '@shared/utils/fetchOgData'; +import { authStorage } from '@shared/utils/authStorage'; +import { extensionBridge } from '@shared/utils/extensionBridge'; import { useMutation, UseMutationResult, @@ -94,17 +96,8 @@ export const usePostSignUp = () => { const newToken = data?.data?.token || data?.token; if (newToken) { - localStorage.setItem('token', newToken); - const sendTokenToExtension = (token: string) => { - window.postMessage( - { - type: 'SET_TOKEN', - token, - }, - window.location.origin - ); - }; - sendTokenToExtension(newToken); + authStorage.setAccessToken(newToken); + extensionBridge.syncToken(newToken); } }, onError: (error) => { diff --git a/apps/client/src/shared/apis/setting/axiosInstance.ts b/apps/client/src/shared/apis/setting/axiosInstance.ts index 42ebd68..1998afc 100644 --- a/apps/client/src/shared/apis/setting/axiosInstance.ts +++ b/apps/client/src/shared/apis/setting/axiosInstance.ts @@ -1,4 +1,6 @@ import axios from 'axios'; +import { authStorage } from '@shared/utils/authStorage'; +import { extensionBridge } from '@shared/utils/extensionBridge'; const noAuthNeeded = [ '/api/v1/auth/token', @@ -18,17 +20,13 @@ const reissueToken = async () => { }; const syncAccessToken = (token: string) => { - localStorage.setItem('token', token); - - window.postMessage( - { type: 'SET_TOKEN', token }, - window.location.origin - ); + authStorage.setAccessToken(token); + extensionBridge.syncToken(token); }; const clearAuthSessionAndRedirect = () => { - localStorage.removeItem('token'); - localStorage.removeItem('refreshToken'); + authStorage.clearSession(); + extensionBridge.logout(); window.location.href = '/onboarding?step=SOCIAL_LOGIN'; }; @@ -42,7 +40,7 @@ const apiRequest = axios.create({ // 요청 인터셉터 apiRequest.interceptors.request.use(async (config) => { - const token = localStorage.getItem('token'); + const token = authStorage.getAccessToken(); if (token) { config.headers.Authorization = `Bearer ${token}`; diff --git a/apps/client/src/shared/components/profilePopup/ProfilePopup.tsx b/apps/client/src/shared/components/profilePopup/ProfilePopup.tsx index 4206d72..7ea92d7 100644 --- a/apps/client/src/shared/components/profilePopup/ProfilePopup.tsx +++ b/apps/client/src/shared/components/profilePopup/ProfilePopup.tsx @@ -2,6 +2,8 @@ import { Icon } from '@pinback/design-system/icons'; import { Button } from '@pinback/design-system/ui'; import { useQueryClient } from '@tanstack/react-query'; import formatRemindTime from '@shared/utils/formatRemindTime'; +import { authStorage } from '@shared/utils/authStorage'; +import { extensionBridge } from '@shared/utils/extensionBridge'; import { useEffect, useRef } from 'react'; import { useNavigate } from 'react-router-dom'; @@ -42,19 +44,9 @@ export default function ProfilePopup({ if (!open) return null; const handleLogout = () => { - localStorage.removeItem('token'); - localStorage.removeItem('email'); - localStorage.removeItem('userId'); + authStorage.clearSession(); queryClient.clear(); - const sendExtensionLogout = () => { - window.postMessage( - { - type: 'Extension-Logout', - }, - window.location.origin - ); - }; - sendExtensionLogout(); + extensionBridge.logout(); navigate('/login'); };