공부 및 일상기록

[React] 관리자페이지 (페이지 권한설정) 만들기 본문

개발/React

[React] 관리자페이지 (페이지 권한설정) 만들기

낚시하고싶어요 2023. 9. 11. 18:36

웹사이트를 만들다 보면 특정 권한이 있는 사람만 볼 수 있는 페이지를 만들어야 하는 경우가 많다.

특정 권한이 없으면 해당 페이지를 들어갈 수 없도록 말이다.

 

혹은 유저가 그 페이지의 경로를 이미 알고 경로를 직접 들어가는 경우를 막아야 한다.

 

이러한 두 가지 경우를 막아보려고 한다.

 

방법은 react-router-dom에서 불러오는 element 컴포넌트를 감싸는 방식이다.

 

function App() {
  return (
      <BrowserRouter>
        <Navbar />
        <Routes>
          <Route path="/" element={<Home />} />
          <Route
            path="/admin"
            element={<Admin />} />
          <Route
            path="/mypage"
            element={<Mypage />} />
          <Route path="/*" element={<NotFound />} />
        </Routes>
      </BrowserRouter>
  );
}

export default App;

간단하게 생각하기 위해 메인페이지와, 관리자페이지, 마이페이지 등 세가지 페이지가 있는 웹사이트가 있다고 가정한다.

 

로그인을 했을 때, 내가 만약 일반 회원이라면 마이페이지에 들어갈 수 있어야 한다. 하지만 로그인을 하지 않은 사람이 경로를 직접 /mypage를 입력한다면 들어갈 수 없어야 하고, 로그인을 했어도 /admin 경로는 들어갈 수 없어야 한다.

 

또한 내가 만약 관리자 회원이라면 마이페이지 뿐만 아니라 admin페이지도 들어갈 수 있어야 한다. 

 

이러한 조건이 있다면 다음과 같은 방법을 생각해 볼 수 있다.

 

Route의 element에 권한을 검사하는 Component를 감싸기

function App() {
  return (
      <BrowserRouter>
        <Navbar />
        <Routes>
          <Route path="/" element={<Home />} />
          <Route
            path="/admin"
            element={<ProtectRouter admin><Admin /></ProtectRouter>} />
          <Route
            path="/mypage"
            element={<ProtectRouter><Mypage /></ProtectRouter>} />
          <Route path="/*" element={<NotFound />} />
        </Routes>
      </BrowserRouter>
  );
}

export default App;

간단하게 <ProtectRouter/> 라는 컴포넌트를 만들고 그 안에서 권한과 로그인 유무를 판별하여 redirect 할지, children을 보여줄지 결정하는 것이다.

 

ProtectRouter

export default function ProtectRouter({ children, admin }) {
  const { user } = useAuthContext();

  //사용자가 없거나, admin 프롭이 있지만 해당유저가 어드민이 아닌 경우
  if (!user || (requireAdmin && !user.isAdmin)) {
    return <Navigate to="/" replace />;
  }
  return children;
}

ProtectRouter는 위 처럼 만들었다.

먼저 여기서 useAuthContext는 유저 정보가 담겨있는 context API로, 로그인을 하면 user정보가 있고, 로그아웃을 하면 user===null 이다. 또한 user 내부에는 isAdmin 이라는 정보가 담겨 있어서 해당 회원이 관리자인지 일반 회원인지 구분할 수 있다.

 

꼭 contextAPI가 아니더라도 로그인 유무나, 관리자 해당 유무를 알 수 있는 정보를 받으면 된다.

 

if문 조건으로는 사용자가 없거나, admin 프롭스가 있지만 해당 유저가 admin이 아닌 경우 이고, 그 경우 react-router-dom의 Navigate를 이용해서 "/"경로로 redirect 시켜주고, replace를  true로 전달하여 히스토리에서 제거한다.

 

만약 if문 조건에 부합하지 않는 경우 children을 그대로 return하여 정상적인 동작을 하도록 한다.