Computer/Front-end

인증 및 권한 구현하기(권한별 routing)

madnaeun 2023. 6. 21. 18:19

진행 이유

  • 서버에서 처리해야 할 작업량을 감소하기 위해서.서버에서 인증을 처리하고, 인증된 사용자들에게 모든 권한을 부여하는 방식은 불필요한 데이터 처리가 발생함. 프론트에서 인증 별 권한을 구현하면 필요한 데이터만 서버로 요청하고, 불필요한 데이터 처리를 줄일 수 있음.
  • 작업 시 사용자의 권한에 맞게 서비스를 제공하려고. 서비스에서 서로 다른 dashboard를 제공해야 하는데 이를 미리 경험해보기 위해 시도함.

고려해야 할 사항: redux등 전역 상태관리를 위한 라이브러리를 적용할 것인가?

상태관리 라이브러리 참고: https://dalaranl.github.io/react/redux-mobx-context/

  • 장점
    • 상태 관리의 편리성: React에서 상태를 관리하면서 상태가 컴포넌트 간에 전달되어야 할 때, 상태를 끌어올리기(uplifting) 패턴을 사용해야 하는 경우가 있음 이 때, 전역 상태를 관리하는 라이브러리를 사용하면 상태를 쉽게 관리할 수 있다.
    • 성능 최적화: 전역 상태를 관리하는 라이브러리는 상태 변경이 발생한 경우, 관련된 컴포넌트만 다시 렌더링되도록 최적화된 방식으로 동작함. 이러한 방식으로 상태 변경을 처리하면, 불필요한 렌더링이 발생하지 않아 성능을 최적화시킬 수 있음.
    • 유지보수성: 전역 상태를 관리하는 라이브러리를 사용하면, 상태 변경이 발생한 경우 모든 컴포넌트에서 해당 상태를 참조하는 부분을 일일히 찾아 수정할 필요가 없음. 때문에 코드 유지보수성이 높아지고, 코드 수정에 대한 위험이 줄어듬.
  • 단점
    • 컴포넌트의 재사용성을 해칠 수 있다.
    • 성능: 전역 상태를 관리하는 라이브러리는 상태 변경 시 모든 컴포넌트에 영향을 미치기 때문에 때문에 불필요한 렌더링이 일어날 가능성이 있음. 또한 라이브러리의 오버헤드 때문에 작은 규모의 애플리케이션에서는 성능 저하가 발생할 수 있다.
    • 코드 복잡성: 전역 상태 관리를 위한 추가적인 코드를 작성해야 하므로 코드의 복잡성이 증가할 수 있음
    • 적용 대상 제한: 모든 상황에서 전역 상태 관리 라이브러리를 사용할 수는 없음. 작은 규모의 애플리케이션에서는 오히려 불필요한 기능이 될 수 있으며, 일부 상황에서는 로컬 상태나 컴포넌트 간 통신 등으로 해결할 수 있는 경우도 있다.
    ==⇒ 때문에  컴포넌트 수가 많지 않고, 테스트하는 수준에서는 redux등을 도입하지 않는게 시간상 더 나을 것 같아 진행하지 않았다.

구현

PrivateRoute

import React from "react";
import { Navigate } from "react-router-dom";
import AuthService from "./auth.service";

//로그인된 사람만 접근 가능
export const PrivateRoute= ({ children }) => {
    const auth =  AuthService.getCurrentUser();//현재 유저 로그인 유무 확인
    return auth ? children : ( //로그인하지 않았을 경우 최초 페이지로 이동
        <>
        < Navigate to="/"/>
        </>);
};

PublicRoute

import React from "react";
import { Navigate } from "react-router-dom";
import AuthService from "./auth.service";

//로그인하지 않은 사람만 접근 가능
export const PublicRoute = ({ children }) => {
    const auth =  AuthService.getCurrentUser();//현재 유저 로그인 유무 확인
    if (auth) {
        return <Navigate to="/home" />;//로그인되어 있을 경우 게시판으로 이동
    } else {
      console.log("No user");
    }
    return children;
};

App

import { React,useEffect } from "react"
import { Routes, Route, Navigate, Outlet } from "react-router-dom";
import Home from "./Page/Home/Home";
import Detail from "./Page/Detail/Detail";
import Login from "./Page/Register_Login/LoginMain";
import SignUp from "./Page/Register_Login/SignUp"
import { createTheme, ThemeProvider } from '@mui/material/styles';
import { PublicRoute,PrivateRoute } from "./services/ProtectedRoute";

const theme = createTheme({
  palette: {
    primary: {
      main:"#FF8800",
      contrastText: "#FFFFFF",}
  },
});

const App=()=>{
  return(
    <ThemeProvider theme={theme}>
      <Routes>
        <Route path="/" element={
          <PublicRoute>
            <Login />
          </PublicRoute>}/>
        <Route path="/register" element={
          <PublicRoute>
            <SignUp/>
          </PublicRoute>}/>
        <Route path="/home" element={
          <PrivateRoute>
            <Home />
          </PrivateRoute>}/>
        <Route path="/detail/*" element={
        <PrivateRoute>
          <Detail />
        </PrivateRoute>} />
      </Routes>
    </ThemeProvider>
  );
};
export default App;

 

➡️ children이 뭐지? : 태그와 태그 사이의 모든 내용을 표시하기 위해 사용되는 특수한 props