[React] Note2. Protected Route

2026. 2. 13. 11:23·dev/React
반응형

Note1. Proetected Route

- Protected Route는 React Router에서 특정 경로 접근 전에 인증/권한을 확인하는 컴포넌트이다. 

- 중요한 자원 (관리자 대시보드 등) 의 UI 노출을 방지할 수 있다. 

하지만 개발자 도구로 우회가 가능하기에 완전한 보안은 불가능하고 서버단에서 API 접근에 대한 보안처리는 반드시 따로 해줘야만 한다. 

이것은 CSR (Client-Side-Rendering)의 한계로 Spring MVC나 Next.js같은 SSR(Server-Side-Rendering) 방식을 사용하는 프레임워크는 Nginx 같은 프록시에서 html 자원 호출 자체를 서버단에서 제한할 수 있으나, CSR은 불가능하기 때문이다. 

 

예시로 사용자가 .../admin 페이지로 접근을 시도하면 Protected Route가 권한을 확인하고, 권한이 있으면 페이지를 표시 권한이 없으면 설정한 페이지로 리다이렉트한다. 

 

Protected Route에서 사용하기 위해 utils/jwt.js에 JWT 어드민 권한 체크 함수를 정의했다. 

export const isAdmin = (): boolean => {

  const token = localStorage.getItem('authToken');
  if (!token) { return false; }

  try {
    const base64Url = token.split('.')[1];
    const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
    const jsonPayload = decodeURIComponent(
      atob(base64)
        .split('')
        .map(function (c) {
          return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
        })
        .join('')
    );
    const payload = JSON.parse(jsonPayload);
    const authorities = payload.authorities || [];
    return Array.isArray(authorities) && authorities.includes('ROLE_ADMIN');
  } catch (error) {
    return false;
  }

};

 

Note2. 403 Forbidden Page

다음으로 권한 없이 관리자 페이지에 접근하면 리다이렉트할 403 페이지를 간단하게 정의한다. 

import { useNavigate } from 'react-router-dom';

const ForbiddenPage = () => {
    const navigate = useNavigate();

    return (
        <div className="min-h-screen bg-white flex items-center justify-center">
            <div className="text-center">
                <h1 className="text-6xl font-bold text-gray-900 mb-4">403</h1>
                <h2 className="text-2xl font-medium text-gray-700 mb-2">접근 권한이 없습니다</h2>
                <p className="text-gray-500 mb-8">이 페이지에 접근할 수 있는 권한이 없습니다.</p>
                <div className="space-x-4">
                    <button
                        onClick={() => navigate(-1)}
                        className="px-6 py-2 bg-gray-200 text-gray-700 rounded hover:bg-gray-300 transition"
                    >
                        이전 페이지
                    </button>
                    <button
                        onClick={() => navigate('/')}
                        className="px-6 py-2 bg-gray-900 text-white rounded hover:bg-gray-800 transition"
                    >
                        홈으로
                    </button>
                </div>
            </div>
        </div>
    );
};

export default ForbiddenPage;

 

Note3. ProtectedRotue

로그인하지 않은 경우에는 로그인 페이지로

로그인 했지만 권한이 없는 경우에는 방금 정의한 403 페이지로 리다이렉트 시킨다. 

import { Navigate } from 'react-router-dom';
import { isAdmin } from '@/utils/jwt';

interface ProtectedRouteProps {
    children: React.ReactNode;
    requireAdmin?: boolean;
}

const ProtectedRoute = ({ children, requireAdmin = false }: ProtectedRouteProps) => {
    if (requireAdmin) {
        const token = localStorage.getItem('authToken');

        // 로그인하지 않은 경우 → 로그인 페이지로 리다이렉트
        if (!token) {
            return <Navigate to="/login" replace />;
        }

        // 로그인했지만 관리자 권한이 없는 경우 → 403 페이지로 리다이렉트
        if (!isAdmin()) {
            return <Navigate to="/403" replace />;
        }
    }

    return <>{children}</>;
};

export default ProtectedRoute;

 

마지막으로 Admin Dashboard로의 접근을 ProtectedRoute로 막아주었다. 

        <Route
          path="/admin"
          element={
            <ProtectedRoute requireAdmin={true}>
              <AdminDashboard />
            </ProtectedRoute>
          }
        />
반응형
저작자표시 비영리 변경금지 (새창열림)

'dev > React' 카테고리의 다른 글

React Note1. state, variable useState, useEffect  (0) 2026.02.07
'dev/React' 카테고리의 다른 글
  • React Note1. state, variable useState, useEffect
novs
novs
https://github.com/novvvv
    반응형
  • novs
    nov.Zip
    novs
  • 전체
    오늘
    어제
    • All (380)
      • Project (2)
        • Rag Blog (2)
      • 🌱 Spring Framework (27)
        • Java Fundamental (13)
        • SpringSecurity (1)
        • Multi Thread Programming (3)
        • Spring Framework (3)
        • JPA (4)
      • 🔓 Security (1)
      • Cloud (2)
        • Docker (1)
        • AWS (1)
      • Mobile Development (0)
      • dev (7)
        • Git (2)
        • React (2)
        • Android (1)
        • Computer Science (2)
      • Algorithm (29)
        • PS With C++ (8)
        • Algorithm (2)
        • BOJ (16)
        • AtCoder (3)
      • Archive (312)
        • 동아리 사이트 개발일지 (3)
        • 카페 주문 시스템 (3)
        • UIKit (2)
        • Swift Language (3)
        • PS With Swift (2)
        • Next.js (3)
        • React (2)
        • Git (1)
        • Linux (3)
        • Vue.js (2)
        • Flutter (11)
        • ...2022 (34)
        • ...2024 (2)
        • C# (14)
        • C&C++ (47)
        • GameDevelop (19)
        • WEB (32)
        • CS (7)
        • Algorithm (13)
        • ProblemSolving (105)
        • Daily (2)
  • 블로그 메뉴

    • 홈
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    BOJ
    알고리즘
    소스코드
    백준
    문제풀이
    STL
    그리디
    js
    자바스크립트
    프로그래머스
    스택
    dp
    C++문법
    javascript
    c#
    C언어
    유니티
    C
    다이나믹프로그래밍
    C++
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
novs
[React] Note2. Protected Route
상단으로

티스토리툴바