Computer/Front-end
인증 및 권한 구현하기(권한별 routing)
madnaeun
2023. 6. 21. 18:19
진행 이유
- 서버에서 처리해야 할 작업량을 감소하기 위해서.서버에서 인증을 처리하고, 인증된 사용자들에게 모든 권한을 부여하는 방식은 불필요한 데이터 처리가 발생함. 프론트에서 인증 별 권한을 구현하면 필요한 데이터만 서버로 요청하고, 불필요한 데이터 처리를 줄일 수 있음.
- 작업 시 사용자의 권한에 맞게 서비스를 제공하려고. 서비스에서 서로 다른 dashboard를 제공해야 하는데 이를 미리 경험해보기 위해 시도함.
고려해야 할 사항: redux등 전역 상태관리를 위한 라이브러리를 적용할 것인가?
상태관리 라이브러리 참고: https://dalaranl.github.io/react/redux-mobx-context/
- 장점
- 상태 관리의 편리성: React에서 상태를 관리하면서 상태가 컴포넌트 간에 전달되어야 할 때, 상태를 끌어올리기(uplifting) 패턴을 사용해야 하는 경우가 있음 이 때, 전역 상태를 관리하는 라이브러리를 사용하면 상태를 쉽게 관리할 수 있다.
- 성능 최적화: 전역 상태를 관리하는 라이브러리는 상태 변경이 발생한 경우, 관련된 컴포넌트만 다시 렌더링되도록 최적화된 방식으로 동작함. 이러한 방식으로 상태 변경을 처리하면, 불필요한 렌더링이 발생하지 않아 성능을 최적화시킬 수 있음.
- 유지보수성: 전역 상태를 관리하는 라이브러리를 사용하면, 상태 변경이 발생한 경우 모든 컴포넌트에서 해당 상태를 참조하는 부분을 일일히 찾아 수정할 필요가 없음. 때문에 코드 유지보수성이 높아지고, 코드 수정에 대한 위험이 줄어듬.
- 단점
- 컴포넌트의 재사용성을 해칠 수 있다.
- 성능: 전역 상태를 관리하는 라이브러리는 상태 변경 시 모든 컴포넌트에 영향을 미치기 때문에 때문에 불필요한 렌더링이 일어날 가능성이 있음. 또한 라이브러리의 오버헤드 때문에 작은 규모의 애플리케이션에서는 성능 저하가 발생할 수 있다.
- 코드 복잡성: 전역 상태 관리를 위한 추가적인 코드를 작성해야 하므로 코드의 복잡성이 증가할 수 있음
- 적용 대상 제한: 모든 상황에서 전역 상태 관리 라이브러리를 사용할 수는 없음. 작은 규모의 애플리케이션에서는 오히려 불필요한 기능이 될 수 있으며, 일부 상황에서는 로컬 상태나 컴포넌트 간 통신 등으로 해결할 수 있는 경우도 있다.
구현
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