2. FrontEnd/React
[ React ] 로그인 안될경우, 로그인 페이지로 리다이렉트 (+예외처리)
HyunJeongE
2024. 10. 2. 09:20
728x90
현재 로그인이 안된 상태에 로그인 페이지로 리다이렉트 하는 기능을 넣었다.
이 과정 중 로그인 페이지 안에 있는 회원가입페이지, 아이디/비밀번호 찾기 페이지에도 접속이 안되고 바로 로그인 페이지로 이동하게 되는 불상사가 발생
이것을 예외처리하는 방법을 기록으로 남기고자 한다.
전코드
import React, { useEffect } from 'react';
import { Route, Routes, Navigate, useNavigate } from 'react-router-dom';
import { ROUTES } from './constants/url'; // 방금 주신 ROUTES 정의를 가져옵니다.
import AuthProvider from './contexts/AuthContext';
import useAuthStore from 'store/useAuthStore';
import './App.css';
import { getCookie } from 'lib/cookie';
export default function App() {
const { isLoggedIn, setIsLoggedIn } = useAuthStore(); // Zustand에서 로그인 상태를 가져옴
const accessToken = getCookie({ name: 'accessToken' }); // 쿠키에서 accessToken 가져오기
const navigate = useNavigate();
// 로그아웃 또는 로그인 상태 변경 시 리디렉션 처리
useEffect(() => {
if (!isLoggedIn && !accessToken) {
// 로그아웃 상태일 때 로그인 페이지로 이동
navigate(ROUTES.LOGIN.path);
} else if (accessToken) {
setIsLoggedIn(true);
}
}, [isLoggedIn, navigate]);
return (
<AuthProvider>
<Routes>
{Object.values(ROUTES).map((route) => (
<Route key={route.path} path={route.path} element={route.element} />
))}
</Routes>
</AuthProvider>
);
}
후코드
import React, { useEffect } from 'react';
import { Route, Routes, Navigate, useNavigate, useLocation } from 'react-router-dom';
import { ROUTES } from './constants/url';
import AuthProvider from './contexts/AuthContext';
import useAuthStore from 'store/useAuthStore';
import './App.css';
import { getCookie } from 'lib/cookie';
export default function App() {
const { isLoggedIn, setIsLoggedIn } = useAuthStore(); // Zustand에서 로그인 상태를 가져옴
const accessToken = getCookie({ name: 'accessToken' }); // 쿠키에서 accessToken 가져오기
const navigate = useNavigate();
const location = useLocation(); // 현재 경로를 가져오기 위해 useLocation 사용
// 로그아웃 또는 로그인 상태 변경 시 리디렉션 처리
useEffect(() => {
const publicPaths = [ROUTES.SIGNUP.path, ROUTES.FIND_PASSWORD.path, ROUTES.FIND_PASSWORD_RESET.path];
// 현재 경로가 로그인하지 않아도 접근 가능한 경로인지 확인
const isPublicPath = publicPaths.includes(location.pathname);
if (!isLoggedIn && !accessToken && !isPublicPath) {
// 로그인되지 않은 상태 && 현재 경로가 로그인 없이 접근 불가능한 페이지일 때 로그인 페이지로 이동
navigate(ROUTES.LOGIN.path);
} else if (accessToken) {
setIsLoggedIn(true);
}
}, [isLoggedIn, navigate, accessToken, setIsLoggedIn, location.pathname]);
return (
<AuthProvider>
<Routes>
{/* 로그인하지 않은 사용자가 접근할 수 있는 경로 */}
{!isLoggedIn ? (
<>
<Route path={ROUTES.SIGNUP.path} element={ROUTES.SIGNUP.element} />
<Route path={ROUTES.FIND_PASSWORD.path} element={ROUTES.FIND_PASSWORD.element} />
<Route path={ROUTES.FIND_PASSWORD_RESET.path} element={ROUTES.FIND_PASSWORD_RESET.element} />
<Route path={ROUTES.LOGIN.path} element={ROUTES.LOGIN.element} />
</>
) : (
<>
{Object.values(ROUTES).map((route) => (
<Route key={route.path} path={route.path} element={route.element} />
))}
</>
)}
{/* 로그인한 사용자가 아닌 경우, 특정 페이지에 접근 시 로그인 페이지로 리디렉션 */}
<Route path="*" element={<Navigate to={isLoggedIn ? ROUTES.NOT_FOUND.path : ROUTES.LOGIN.path} />} />
</Routes>
</AuthProvider>
);
}
useLocation으로 현재 경로를 가져오는걸로 사용하였다.
useEffect에 publicPath를 넣고 조건문에 맞는지 확인을 하는 조건을 추가 하였다.