2. FrontEnd/React / / 2024. 10. 2. 09:20

[ React ] 로그인 안될경우, 로그인 페이지로 리다이렉트 (+예외처리)

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를 넣고 조건문에 맞는지 확인을 하는 조건을 추가 하였다. 

  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유