내게 Private Router가 필요했던 이유
위와 같이 페이지의 구분이 생겨 인증(로그인) 여부에 대해 체크를 해주는 부분을 Private Router에서 해주었다.
Private Router의 역할
EX1)
로그인한 사용자가 URL을 통해 로그인 페이지로 진입했을 경우 접근을 못하도록 막아 주어야 한다
EX2)
로그인하지 않은 사용자가 회원만 접근 가능한 마이페이지에 URL을 통해 진입했을 경우 접근을 못하도록 막아 주어야 한다
간단한 예제
PrivateRouter.tsx
import { ReactElement } from 'react';
import { Navigate, Outlet } from 'react-router-dom';
interface PrivateRouteProps {
children ?: ReactElement; // Router.tsx에서 PrivateRoute가 감싸고 있는 Componet Element
authentication : boolean; // true :인증을 반드시 해야하만 접속가능, false : 인증을 반디스 안해야만 접속 가능
}
export default function PrivateRoute({authentication}:PrivateRouteProps):React.ReactElement|null {
/**
* 로그인 했는지 여부
* 로그인 했을 경우 : true 라는 텍스트 반환
* 로그인 안했을 경우 : null or false(로그아웃 버튼 눌렀을경우 false로 설정) 반환
*/
const isAuthenticated = sessionStorage.getItem("isAuthenticated");
if(authentication) {
// 인증이 반드시 필요한 페이지
// 인증을 안했을 경우 로그인 페이지로, 했을 경우 해당 페이지로
return (isAuthenticated === null || isAuthenticated === 'false') ? <Navigate to="/login"/> : <Outlet/>;
} else {
// 인증이 반드시 필요 없는 페이지
// 인증을 안햇을 경우 해당 페이지로 인증을 한 상태일 경우 main페이지로
return (isAuthenticated === null || isAuthenticated === 'false') ? <Outlet/> : <Navigate to='/'/>;
}
}
Router.tsx
import {BrowserRouter, Routes, Route} from 'react-router-dom';
import LoginPage from '../pages/LoginPage';
import MainPage from '../pages/MainPage';
import MyPage from '../pages/MyPage';
import PrivateRoute from './PrivateRoute';
export default function Router() {
return (
<BrowserRouter>
<Routes>
{/* 인증 여부 상관 없이 접속 가능한 페이지 정의 */}
<Route index element={<MainPage/>}/>
{/* 인증을 반드시 하지 않아야만 접속 가능한 페이지 정의 */}
<Route element={<PrivateRoute authentication={false}/>}>
<Route path="/login" element={<LoginPage/>} />
</Route>
{/* 인증을 반드시 해야지만 접속 가능한 페이지 정의 */}
<Route element={<PrivateRoute authentication={true}/>}>
<Route path="/mypage" element={<MyPage/>} />
</Route>
</Routes>
</BrowserRouter>
)
}
App.tsx
import Router from './routes';
function App() {
return (
<Router/>
);
}
export default App;
MainPage.tsx
import { useState } from 'react';
import { useNavigate } from 'react-router';
export default function MainPage() {
// const isAuthenticated = sessionStorage.getItem('isAuthenticated');
const [isAuthenticated, setIsAuthenticated] = useState<string|null>(sessionStorage.getItem('isAuthenticated'));
const navigate = useNavigate();
return (
<>
<h1>Main Page</h1>
<div>로그인 여부 상관없이 누구나 접속 가능!</div>
{
isAuthenticated === null || isAuthenticated === 'false' ? <button onClick={()=>{
navigate("/login");
}}>로그인</button>: <div><button onClick={()=>{
setIsAuthenticated("false");
sessionStorage.setItem('isAuthenticated', "false");
}}>로그아웃</button><button onClick={() => {navigate("/mypage")}}>myPage로 이동</button></div>
}
</>
);
}
LoginPage.tsx
import { useNavigate } from 'react-router';
export default function LoginPage() {
const navigate = useNavigate();
return (
<>
<h1>Login Page</h1>
<div>로그인 하지 않아야만 접속 가능</div>
<button onClick={() => {
sessionStorage.setItem('isAuthenticated', 'true');
// 메인으로 이동
navigate("/")
}}>로그인 하기</button>
</>
)
}
MyPage.tsx
export default function MyPage() {
return(
<>
<h1>My Page</h1>
<div>로그인해야만 접속 가능</div>
</>
)
}
github : https://github.com/anonymous-planets/anonymous-planet-react
해당 내용 찾고있었는데 친절한 게시글 감사합니다‼️