From 8794a32beef77491dad77da70aeec8dd7708fc0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=84=B8=EB=AF=BC?= <89172499+semnil5202@users.noreply.github.com> Date: Tue, 30 Apr 2024 02:27:25 +0900 Subject: [PATCH] =?UTF-8?q?Refactor/#125-re:=20401=20=EC=97=90=EB=9F=AC=20?= =?UTF-8?q?=EC=8B=9C=20=EC=9E=90=EB=8F=99=20=EB=A1=9C=EA=B7=B8=EC=95=84?= =?UTF-8?q?=EC=9B=83=20=EB=B0=8F=20=EC=9E=AC=20=EB=A1=9C=EA=B7=B8=EC=9D=B8?= =?UTF-8?q?=20=EC=9C=A0=EB=8F=84=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=20(#129)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: NeedAuth 기능을 ApiErrorBoundary에 위임 미로그인 사용자는 401 에러가 발생하므로 이를 ApiErrorBoundary에서 감지하여 라우팅할 수 있도록 합니다. * refactor: Login 페이지에서 메인페이지로 가는 링크 텍스트 추가 --- .../ErrorBoundary/ApiErrorBoundary.tsx | 21 +++++++--- src/pages/Login/Login.tsx | 13 ++++++ src/pages/NeedAuth.tsx | 26 ------------ src/router.tsx | 40 +------------------ 4 files changed, 31 insertions(+), 69 deletions(-) delete mode 100644 src/pages/NeedAuth.tsx diff --git a/src/components/ErrorBoundary/ApiErrorBoundary.tsx b/src/components/ErrorBoundary/ApiErrorBoundary.tsx index 8da229e5..2e3a7d83 100644 --- a/src/components/ErrorBoundary/ApiErrorBoundary.tsx +++ b/src/components/ErrorBoundary/ApiErrorBoundary.tsx @@ -28,7 +28,7 @@ type State = } | { error: AxiosError; - errorDetail: 'network' | 'unauthorized'; + errorDetail: 'server' | 'unauthorized' | 'auth-expired'; }; class ErrorBoundary extends Component { @@ -59,16 +59,23 @@ class ErrorBoundary extends Component { } if (error.response?.status === 401) { + if (!localStorage.getItem('userToken')) { + return { + error, + errorDetail: 'unauthorized', + }; + } + return { error, - errorDetail: 'unauthorized', + errorDetail: 'auth-expired', }; } if (error.response?.status >= 400) { return { error, - errorDetail: 'network', + errorDetail: 'server', }; } } @@ -82,7 +89,7 @@ class ErrorBoundary extends Component { componentDidCatch(): void { const { errorDetail } = this.state; - if (errorDetail === 'unauthorized') { + if (errorDetail === 'auth-expired') { localStorage.removeItem('userToken'); localStorage.removeItem('user'); @@ -96,6 +103,10 @@ class ErrorBoundary extends Component { } if (this.state.errorDetail === 'unauthorized') { + return ; + } + + if (this.state.errorDetail === 'auth-expired') { return ( <> @@ -104,7 +115,7 @@ class ErrorBoundary extends Component { ); } - if (this.state.errorDetail === 'network') { + if (this.state.errorDetail === 'server') { if (this.props.fallback) { const FallbackComponent = this.props.fallback.type; const fallbackProps = { diff --git a/src/pages/Login/Login.tsx b/src/pages/Login/Login.tsx index 11057c7f..cfe4ae82 100644 --- a/src/pages/Login/Login.tsx +++ b/src/pages/Login/Login.tsx @@ -1,5 +1,6 @@ import styled from '@emotion/styled'; import { Spacer, Text, theme, SVGLoginKakao, SVGLoginNaver, SVGLoginLogo, Flex } from 'concept-be-design-system'; +import { useNavigate } from 'react-router-dom'; import SEOMeta from '../../components/SEOMeta/SEOMeta'; import { BASE_URL } from '../../constants'; @@ -7,6 +8,8 @@ import { BASE_URL } from '../../constants'; const REQUEST_URL = `${BASE_URL}/oauth/kakao`; const Login = () => { + const navigate = useNavigate(); + const onClickOauthKakao = () => { window.location.href = REQUEST_URL; }; @@ -37,6 +40,11 @@ const Login = () => { 네이버 로그인 + + + navigate('/')}> + 메인페이지로 가기 + ); @@ -75,3 +83,8 @@ const TextWrapper = styled.div` height: 100%; width: 100%; `; + +const LinkText = styled(Text)` + text-decoration: underline; + cursor: pointer; +`; diff --git a/src/pages/NeedAuth.tsx b/src/pages/NeedAuth.tsx deleted file mode 100644 index 07e63a83..00000000 --- a/src/pages/NeedAuth.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import { ReactNode, useEffect } from 'react'; -import { useNavigate } from 'react-router-dom'; - -interface Props { - children: ReactNode; - withAuth: boolean; - to?: string; -} - -const getUserTokenInLocalStorage = () => localStorage.getItem('userToken'); - -function NeedAuth({ children, withAuth, to = '/login' }: Props) { - const navigate = useNavigate(); - - useEffect(() => { - const isAuthorization: boolean = getUserTokenInLocalStorage() !== null; - - if (withAuth && !isAuthorization) { - navigate(to); - } - }); - - return <>{children}; -} - -export default NeedAuth; diff --git a/src/router.tsx b/src/router.tsx index b804385c..3d14c7a7 100644 --- a/src/router.tsx +++ b/src/router.tsx @@ -9,7 +9,6 @@ import FeedDetailPage from './pages/FeedDetail/FeedDetail.page'; import Agreement from './pages/Login/Agreement'; import KakaoRedirect from './pages/Login/KakaoRedirect'; import Login from './pages/Login/Login'; -import NeedAuth from './pages/NeedAuth'; import NotFound from './pages/NotFound'; import More from './pages/Profile/More.page'; import Profile from './pages/Profile/Profile.page'; @@ -21,10 +20,9 @@ import WriteEditPage from './pages/WriteEdit/WriteEdit.page'; interface RouteElement { path: string; element: ReactNode; - isAuth: boolean; redirectPath?: string; errorElement?: ReactNode; - children: { path: string; element: ReactNode; withAuth: boolean }[]; + children: { path: string; element: ReactNode }[]; } const withAsyncBoundary = (children: ReactNode) => ( @@ -37,90 +35,56 @@ const routes: RouteElement[] = [ { path: '/', element: , - isAuth: false, errorElement: , children: [ { path: '', element: withAsyncBoundary(), - withAuth: false, }, { path: '/feed/:id', element: withAsyncBoundary(), - withAuth: true, }, { path: '/write', element: withAsyncBoundary(), - withAuth: true, }, { path: '/write-edit', element: withAsyncBoundary(), - withAuth: true, }, { path: '/login', element: , - withAuth: false, }, { path: '/oauth/redirected/kakao', element: , - withAuth: false, }, { path: '/profile/:id', element: withAsyncBoundary(), - withAuth: true, }, { path: '/profile-edit', element: withAsyncBoundary(), - withAuth: true, }, { path: '/profile/:id/more', element: , - withAuth: true, }, - { path: '/agreement', element: , - withAuth: false, }, { path: '/sign-up', element: withAsyncBoundary(), - withAuth: false, }, ], }, ]; -const router = createBrowserRouter( - routes.map((route) => { - const childrenRoutes = route.children?.map((childRoute) => { - if (childRoute.withAuth) { - return { - path: childRoute.path, - element: {childRoute.element}, - }; - } - - return { - path: childRoute.path, - element: childRoute.element, - }; - }); - - return { - ...route, - children: childrenRoutes, - }; - }), -); +const router = createBrowserRouter(routes); export default router;