diff --git a/src/components/common/Header.tsx b/src/components/common/Header.tsx index 152dd7df..63782aee 100644 --- a/src/components/common/Header.tsx +++ b/src/components/common/Header.tsx @@ -45,9 +45,9 @@ export default function Header() { diff --git a/src/components/user/auth-form/ProfileImageContainer.tsx b/src/components/user/auth-form/ProfileImageContainer.tsx index fdd5c39c..c961f47d 100644 --- a/src/components/user/auth-form/ProfileImageContainer.tsx +++ b/src/components/user/auth-form/ProfileImageContainer.tsx @@ -61,9 +61,6 @@ export default function ProfileImageContainer({ imageUrl, setImageUrl }: Profile } uploadImageMutate({ file }); - - const localImageUrl = URL.createObjectURL(file); - setImageUrl(localImageUrl); }; const handleRemoveImg = () => { diff --git a/src/mocks/services/authServiceHandler.ts b/src/mocks/services/authServiceHandler.ts index cbc9b51f..fe99da22 100644 --- a/src/mocks/services/authServiceHandler.ts +++ b/src/mocks/services/authServiceHandler.ts @@ -208,10 +208,7 @@ const authServiceHandler = [ }), // 액세스 토큰 갱신 API - http.post(`${BASE_URL}/user/refresh`, async ({ cookies, request }) => { - const accessToken = request.headers.get('Authorization'); - if (!accessToken) return new HttpResponse(null, { status: 401 }); - + http.post(`${BASE_URL}/user/refresh`, async ({ cookies }) => { const { refreshToken, refreshTokenExpiresAt } = cookies; const cookieRefreshToken = Cookies.get('refreshToken'); @@ -228,7 +225,7 @@ const authServiceHandler = [ return HttpResponse.json({ message: '리프레시 토큰이 만료되었습니다.' }, { status: 401 }); } - const userId = convertTokenToUserId(accessToken); + const userId = convertTokenToUserId(refreshToken); if (!userId) return new HttpResponse(null, { status: 401 }); const newAccessToken = generateDummyToken(userId); diff --git a/src/routes/AfterLoginRoute.tsx b/src/routes/AfterLoginRoute.tsx index e3c91b49..f2d5e406 100644 --- a/src/routes/AfterLoginRoute.tsx +++ b/src/routes/AfterLoginRoute.tsx @@ -1,11 +1,38 @@ +import { useEffect, type PropsWithChildren } from 'react'; +import { Navigate, Outlet, useNavigate } from 'react-router-dom'; +import useToast from '@hooks/useToast'; import useStore from '@stores/useStore'; -import type { PropsWithChildren } from 'react'; -import { Navigate, Outlet } from 'react-router-dom'; +import { getAccessToken } from '@services/authService'; export default function AfterLoginRoute({ children }: PropsWithChildren) { - const { isAuthenticated, userInfo } = useStore(); + const { toastError } = useToast(); + const navigate = useNavigate(); + const { onLogout, onLogin, clearUserInfo, accessToken, isAuthenticated } = useStore(); - if (!isAuthenticated && !userInfo.userId) return ; + useEffect(() => { + const autoRefreshToken = async () => { + try { + const refreshResponse = await getAccessToken(); + const newAccessToken = refreshResponse.headers.authorization; + + if (!newAccessToken) throw new Error('토큰 발급에 실패했습니다.'); + + onLogin(newAccessToken.split(' ')[1]); + } catch (error) { + // 토큰 갱신 실패 시 처리 + toastError('로그인 정보가 만료되었습니다. 다시 로그인 해주세요.'); + setTimeout(() => { + onLogout(); + clearUserInfo(); + navigate('/signin', { replace: true }); + }, 2000); + } + }; + + if (isAuthenticated && !accessToken) autoRefreshToken(); + }, [accessToken]); + + if (!isAuthenticated) return ; return children || ; } diff --git a/src/routes/BeforeLoginRoute.tsx b/src/routes/BeforeLoginRoute.tsx index 6f50b7e9..7aacd36b 100644 --- a/src/routes/BeforeLoginRoute.tsx +++ b/src/routes/BeforeLoginRoute.tsx @@ -3,9 +3,9 @@ import type { PropsWithChildren } from 'react'; import { Navigate, Outlet } from 'react-router-dom'; export default function BeforeLoginRoute({ children }: PropsWithChildren) { - const { isAuthenticated, userInfo } = useStore(); + const { isAuthenticated } = useStore(); - if (isAuthenticated || userInfo.userId) return ; + if (isAuthenticated) return ; return children || ; } diff --git a/src/stores/useStore.ts b/src/stores/useStore.ts index e5be59fa..8d1ae3c3 100644 --- a/src/stores/useStore.ts +++ b/src/stores/useStore.ts @@ -136,6 +136,8 @@ export const useStore = create()( })), partialize: (state) => ({ userInfo: state.userInfo, + isAuthenticated: state.isAuthenticated, + isVerified: state.isVerified, }), }, ),