⚛️React | Router로 로그인 인증 및 접근 제한하기

dayannne·2023년 10월 12일
1

React

목록 보기
4/13
post-thumbnail

✨ 시작하며

보통 페이지를 만들 때 로그인을 해야만 접근할 수 있는 페이지와 그렇지 않은 페이지가 나뉜다.
보통은 로그인 여부를 체크해서 필요한 페이지, 접근경로만 보여 주었지만 URL 입력을 통해 언제든 접근할 수 있는 부분에 대해서 고민이 되었다.
각 페이지마다 체크하거나, 재사용 가능한 모듈을 만들거나의 방법도 있는데, 아예 Router에서 로그인 인증 / 접근 제한을 설정하는 방법이 있다고 하여 프로젝트에 적용해 보기로 했다.


1. 파일 설정

  • App.tsx
import styled from 'styled-components';
import AutoRouter from './router/AutoRouter';

const App = () => {
  return (
    <>
      <GlobalStyle />
      <AutoRouter />
    </>
  );
};

export default App;
  • router/AutoRouter.tsx

Router를 App컴포넌트에서 분리해 AutoRouter 파일에서 설정하고 있어서, 해당 파일을 수정해 구현했다.


2. RouterInfo

경로(path), 렌더링할 컴포넌트(element), 그리고 사용자 인증이 필요한지 여부를 나타내는 속성(withAuthorization)으로 이뤄진 라우팅에 필요한 경로 정보(RouterInfo)를 배열로 정의해 두었다.

import {
  BrowserRouter as Router,
  Routes,
  Route,
  Navigate,
} from 'react-router-dom';

// ...

type RouterItem = {
  path: string;
  element: JSX.Element;
  withAuthorization: boolean;
};

const RouterInfo: RouterItem[] = [
  { path: '/', element: <Home />, withAuthorization: false },
  { path: '/account/login', element: <Login />, withAuthorization: false },
  { path: '/account/signup', element: <Signup />, withAuthorization: false },
  { path: '/my/page', element: <Login />, withAuthorization: true },
  { path: '/my/seller_center', element: <Signup />, withAuthorization: true },
  { path: '/my/cart', element: <Cart />, withAuthorization: true },
  {
    path: '/products/:id',
    element: <ProductDetail />,
    withAuthorization: false,
  },
];
  • withAuthorization - 로그인 된 상태에서 접근할 수 있는 페이지는 true, 로그인 상관 없이 접근 가능한 페이지는 false로 설정

3. Authorization

로그인 인증을 확인하고 처리하기 위한 컴포넌트(Authorization)를 만든다.
로그인이 되었는지 아닌지의 상태를 확인하기 위해 로그인 시 localstorage.setItem로 로컬스토리지에 저장했던 token 값을 이용했다.

interface AuthorizationProps {
  redirectTo: string;
  children: React.ReactNode;
}
const isAuthenticated: string | null = localStorage.getItem('token');

const Authorization = ({
  redirectTo,
  children,
}: AuthorizationProps) => {
  if (isAuthenticated) {
    return <>{children}</>;
  } else {
    return <Navigate to={redirectTo} />;
  }
};
  • localStorage에서 token을 가져와 isAuthenticated에 담는다.
  • token 값이 존재하면(로그인 된 상태 / 사용자 인증) 해당 페이지로 이동시키고, 인증되지 않은 경우(로그인 되지 않은 상태) 지정한 경로로 리디렉션하여 페이지 액세스를 제어한다.

4. 렌더링

마지막으로, 위에서 정의한 경로 정보와 인증 컴포넌트를 이용해 렌더링한다.
RouterInfo에서 설정한 속성 withAuthorization이 false인 페이지는 그대로 렌더링하고, withAuthorization이 true인 페이지는 Authorization 컴포넌트를 통해 인증을 거쳐 인증에 실패하면 로그인 페이지 경로/account/login로 이동하도록 설정하였다.

const AutoRouter = () => {


  return (
    <Router>
      <Routes>
        {RouterInfo.map((route) => {
          return (
            <Route
              key={route.path}
              path={route.path}
              element={
                route.withAuthorization ? (
                  <Authorization
                    isAuthenticated={isAuthenticated}
                    redirectTo='/account/login'
                  >
                    {route.element}
                  </Authorization>
                ) : (
                  route.element
                )
              }
            />
          );
        })}
      </Routes>
    </Router>
  );
};

export default AutoRouter;

profile
☁️

2개의 댓글

comment-user-thumbnail
2024년 2월 28일

하나 물어봐도 될까요? 토큰을 가져올때 RefreshToken인가요? AccessToken인가요?

1개의 답글