리액트 라우트 권한 설정 (로그인 여부에 따른 라우트 분리)

1
post-thumbnail

🎀 기존 라우트

routes/routes.tsx

import { lazy } from 'react';
import { createBrowserRouter, createRoutesFromElements, Route } from 'react-router-dom';
import Loading from './loading';

const LandingPage = lazy(() => import('@pages/landing'));
const SignInPage = lazy(() => import('@pages/sign-in'));
const SignUpPage = lazy(() => import('@pages/sign-up'));
const DashBoardPage = lazy(() => import('@pages/dashboard'));
const DashBoardTestPage = lazy(() => import('@pages/dashboard-test'));
const NotFoundPage = lazy(() => import('@pages/not-found'));

const PrimaryRoute = (
  <Route path='/' element={<Loading />}>
    <Route index element={<LandingPage />} />
    <Route path='sign-in' element={<SignInPage />} />
    <Route path='sign-up' element={<SignUpPage />} />
    <Route path='dashboard' element={<DashBoardPage />} />
    <Route path='dashboard-test' element={<DashBoardTestPage />} />
    <Route path='*' element={<NotFoundPage />} />
  </Route>
);

const baseRoute = createRoutesFromElements(PrimaryRoute);

export const router = createBrowserRouter(baseRoute);

react lazy loading을 활용해서 라우트를 완성시켰었다.
lazy loading 관련 포스팅 보러 가기

📌 문제점

로그인 여부를 체크하는 함수를 렌더링 될 때 마다 실행시켜 줘야했다.
이렇게 하니까 권한 없는 페이지로 우선 이동한 뒤 튕겼다.
한마디로 권한 없는 페이지를 구경할 수 있게 되는 것이다. (1초도 안되는 시간이지만)

하지만 권한 없는 페이지는 아예 구경도 못하게 만들어야 정상.

🎀 라우트에서 권한 분리하자

routes/protected-routes/index.tsx

가보자고.

interface PrivateRouteProps {
  children?: ReactElement;
  authentication: boolean;
}

const PrivateRoutes = ({ authentication }: PrivateRouteProps): React.ReactElement | null => {
  // 로그인 했을 경우 true
  // 로그인 하지않았을 경우 false
  const isAuthenticated = !!Cookies.get('accessToken');

  if (authentication) {
    // 로그인 상태일 때 접근 가능
    return isAuthenticated === null || isAuthenticated === false ? <Navigate to='/sign-in' /> : <Outlet />;
  } else {
    // 로그인 상태가 아닐때만 접근 가능
    return isAuthenticated === null || isAuthenticated === false ? <Outlet /> : <Navigate to='/dashboard' />;
  }
};
  1. 로그인 상태일 때 접근 가능한 페이지
  • 로그인 상태가 아니라면 ? <로그인 페이지로 이동> : <하위 페이지 보여줌>
  1. 로그인 상태가 아닐 때 접근 가능한 페이지
  • 로그인 상태가 아니라면 ? <하위 페이지 보여줌> : <대시보드 페이지로 이동>

이렇게 두개로 나뉘어지도록 했다.

🎀 마무리 작업

그럼 다시 라우트 페이지로 돌아와서 작업 마무리해 보겠다.

routes/protected-routes/index.tsx

const PrimaryRoute = (
  <Route path='/' element={<Loading />}>
    // 로그인 상태가 아닐 때 접근 가능한 페이지
    <Route element={<ProtectedRoutes authentication={false} />}>
      <Route index element={<LandingPage />} />
      <Route path='sign-in' element={<SignInPage />} />
      <Route path='sign-up' element={<SignUpPage />} />
    </Route>
    // 로그인 상태일 때 접근 가능한 페이지
    <Route element={<ProtectedRoutes authentication={true} />}>
      <Route path='/' element={<Layout />}>
        <Route path='dashboard' element={<DashBoardPage />} />
        <Route path='dashboard-test' element={<DashBoardTestPage />} />
      </Route>
    </Route>
    // 로그인 여부와 상관없는 페이지
    <Route path='*' element={<NotFoundPage />} />
  </Route>
);

최종적으로 이렇게 마무리가 되었다.
테스트 해봤는데 의도한대로 잘 나온다!

  • 공유된 링크 클릭시, 로그인 상태가 아니라면 로그인 페이지로 이동함

권한 없는 페이지 접근은 꿈.도.꾸.지.마!

profile
일단 해. 그리고 잘 되면 잘 된 거, 잘 못되면 그냥 해본 거!

0개의 댓글