Гид по технологиям

Защищённые маршруты в React: настройка и примеры

5 min read React Обновлено 30 Dec 2025
Защищённые маршруты в React
Защищённые маршруты в React

TL;DR

Если нужно ограничить доступ к страницам в одностраничном приложении на React, используйте защищённые маршруты. Простой способ — хранить состояние входа в компоненте верхнего уровня и оборачивать приватные маршруты компонентом Protected, который перенаправляет неаутентифицированных пользователей. Для боевого приложения добавьте серверную проверку, контекст, JWT и проверки ролей.

замок на фоне кода на экране компьютера

Что такое защищённые маршруты

Защищённые маршруты — это маршруты, доступные только авторизованным пользователям. Приложение должно проверить условия доступа (например, состояние входа или роль пользователя) и либо отобразить запрошенный компонент, либо перенаправить на страницу входа/информационную страницу.

Коротко: защищённые маршруты реализуют контроль доступа на клиенте и обычно дополняются проверками на сервере для безопасности.

Важно: клиентская защита удобна для UX и маршрутизации, но не заменяет серверные проверки данных и API-эндпоинтов.

Основные варианты реализации (кратко)

  • Высший компонент (HOC) или обёртка, возвращающая либо children, либо перенаправление.
  • Компонент-роутер, принимающий функцию проверки (render-prop).
  • Хук useAuth + Context, чтобы валидность была доступна в любом компоненте.
  • Серверная валидация и проверка JWT при каждом API-запросе.

Создание базового React-приложения

Создайте приложение с помощью create-react-app:

npx create-react-app protect-routes-react

Перейдите в папку и запустите приложение:

cd protect-routes-react
npm start

Откройте проект в редакторе и замените содержимое App.js минимальным кодом, чтобы начать с чистого листа:

function App() {
  return 
; } export default App;

Теперь можно настраивать маршруты.

Установка react-router-dom

npm install react-router-dom

В этом примере мы сделаем три страницы:

  • Home — публичная (страница входа/лендинг).
  • Profile — приватная, видна только вошедшим пользователям.
  • About — публичная.

Навигация

Создайте компонент Navbar.js с навигационными ссылками. Используйте Link из react-router-dom:

import { Link } from "react-router-dom";
const Navbar = () => {
  return (
    
  );
};
export default Navbar;

Маршруты в App.js

Добавьте маршруты для трёх страниц:

import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import Navbar from "./Navbar";
import Home from "./Home";
import Profile from "./Profile";
import About from "./About";

function App() {
  return (
    
      
      
        } />
        } />
        } />
      
    
  );
}
export default App;

Создайте простые компоненты Home.js, Profile.js и About.js:

// Home.js
const Home = () => {
  return 

Home page

; }; export default Home; // Profile.js const Profile = () => { return

Profile Page

; }; export default Profile; // About.js const About = () => { return

About page

; }; export default About;

Простая (фейковая) аутентификация

Для демонстрации используем useState, чтобы эмулировать вход и выход пользователя. В App.js:

import { Routes, Route, BrowserRouter } from "react-router-dom";
import { useState } from "react";
// другие импорты: Navbar, Home, About, Profile, Protected

function App() {
  const [isLoggedIn, setIsLoggedIn] = useState(null);
  const logIn = () => setIsLoggedIn(true);
  const logOut = () => setIsLoggedIn(false);

  return (
    
      
      {isLoggedIn ? (
        
      ) : (
        
      )}
      
        {/* маршруты будут здесь */}
      
    
  );
}
export default App;

Кнопки переключают состояние входа и помогают протестировать защищённые маршруты.

Компонент Protected

Создайте файл Protected.js, который проверяет isLoggedIn и либо отдаёт children, либо перенаправляет на домашнюю страницу с помощью Navigate:

import { Navigate } from "react-router-dom";

const Protected = ({ isLoggedIn, children }) => {
  if (!isLoggedIn) {
    return ;
  }
  return children;
};
export default Protected;

Использование в маршруте Profile:


      
    
  }
/>

Полный App.js с защитой:

import { Routes, Route, BrowserRouter } from "react-router-dom";
import { useState } from "react";
import Navbar from "./Navbar";
import Protected from "./Protected";
import Home from "./Home";
import About from "./About";
import Profile from "./Profile";

function App() {
  const [isLoggedIn, setIsLoggedIn] = useState(null);
  const logIn = () => setIsLoggedIn(true);
  const logOut = () => setIsLoggedIn(false);
  return (
    
      
{isLoggedIn ? ( ) : ( )} } /> } /> } />
); } export default App;

Что дальше: роль и RBAC

Для более тонкого контроля (RBAC — role-based access control) расширьте Protected так, чтобы он принимал требуемую роль и сравнивал её с ролью пользователя. Роли обычно поставляются из токена (JWT) или из профиля пользователя на бэкенде.

Пример расширения интерфейса Protected:

// Пример интерфейса использования

  

Идея: если роль пользователя не соответствует requiredRole, перенаправлять на “403” или отображать сообщение “Доступ запрещён”.

Альтернативные подходы (когда этот способ не подходит)

  • Если авторизация рассчитывается на основе JWT, храните токен в httpOnly cookie и выполняйте валидацию на сервере при каждом запросе.
  • Для крупных приложений используйте Context + кастомный хук useAuth, чтобы не передавать isLoggedIn через пропсы.
  • HOC (higher-order component) удобен для повторного использования логики вокруг компонентов.
  • Серверный рендеринг (SSR) требует проверки на сервере и передачи состояния в HTML.

Когда этот способ не подходит: если требуется строгая безопасность данных — нельзя полагаться лишь на клиентские проверки. Любой приватный API должен валидировать токен и права доступа на сервере.

Модель мышления и эвристики (mental models)

  • “Client-side guard” — удобный UX: на клиенте быстро скрывает/перенаправляет, но не защищает данные.
  • “Server-side gate” — единственный надёжный барьер для данных и действий.
  • Делайте проверку прав в двух слоях: клиент (UX) + сервер (безопасность).

Правило большого пальца: проверяйте минимально необходимые права (least privilege) и не поощряйте хранение секретов в localStorage.

Контроль безопасности и рекомендации

  • Не храните токены в localStorage, если можно использовать httpOnly cookie.
  • Всегда проверяйте JWT/сессию на сервере перед возвратом приватных данных.
  • Обновляйте зависимости (react-router-dom) и следите за изменениями API между версиями (v5 → v6 существенно меняет синтаксис Routes/Route).

Критерии приёмки

  • Приватная страница возвращает при isLoggedIn === false или null.
  • После успешного входа — доступ к приватной странице возможен.
  • При отсутствии прав пользователя (роль) — показывается страница 403 либо перенаправление.
  • Серверные API возвращают 401/403 при неавторизованных запросах.

Тесты и случаи приёма

  • Попытка открыть /profile без входа → перенаправление на / (или /login).
  • Вход → кнопка меняется с Login на Logout → доступ к /profile.
  • Пользователь с ролью user пытается открыть /admin → 403.
  • Истечение срока JWT → запросы возвращают 401, клиент перенаправляет на вход.

Чек-лист для ролей (role-based checklist)

  • Есть поле role в профиле пользователя.
  • Protected умеет принимать requiredRole.
  • UI показывает понятное сообщение при недостатке прав.
  • Все приватные API проверяют роль на сервере.

Мини-методология внедрения (шаги)

  1. Добавьте учет состояния аутентификации (Context/useState).
  2. Реализуйте Protected-компонент и оберните приватные маршруты.
  3. Подключите механизм входа (фейковый или реальный с JWT).
  4. Добавьте проверку ролей (requiredRole) при необходимости.
  5. Тестируйте случаи 401/403 и сценарии истечения сессии.
  6. Перенесите проверку на сервер для защищённых API.

Совместимость и миграция

  • react-router-dom v6 использует / и элемент element={<…/>}. При миграции с v5 учтите изменения API.
  • Для TypeScript добавьте типы для Protected: React.PropsWithChildren<{ isLoggedIn: boolean; requiredRole?: string; userRole?: string; }>

Короткая галерея погрешностей (edge cases)

  • Пользователь вручную вводит URL приватного раздела — Protected перенаправляет, но пользователь может видеть UI-элементы до редиректа (мигание). Решение: скрывать UI на уровне родителя или показывать загрузчик при асинхронной проверке.
  • Асинхронная проверка токена — Protected должен поддерживать состояние pending и показывать прелоадер.

Глоссарий (1 строка)

  • Protected: компонент-обёртка, контролирующий доступ к дочерним компонентам.
  • Navigate: компонент react-router-dom для программного перехода.
  • RBAC: контроль доступа на основе ролей.

Заключение

Защищённые маршруты улучшают UX и помогают структурировать доступ внутри SPA на React. Для реальной безопасности всегда комбинируйте клиентские проверки (Protected, Context, хуки) с серверной аутентификацией и проверкой прав. Начните с простого Protected-компонента, затем эволюционируйте к Context + JWT + серверным проверкам ролей.

Важно: клиентская защита не является заменой серверной авторизации.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Скачать приложения на Samsung Smart TV
Гайды

Скачать приложения на Samsung Smart TV

Как очистить ненужные файлы в Windows 10
Windows

Как очистить ненужные файлы в Windows 10

Как создать красивое боке — советы и настройки
Фотография

Как создать красивое боке — советы и настройки

Как создать блок‑схему в Excel — подробное руководство
Office

Как создать блок‑схему в Excel — подробное руководство

Как смотреть Олимпиаду 2024: лучшие стрим‑опции
Стриминг

Как смотреть Олимпиаду 2024: лучшие стрим‑опции

Управление Samsung Smart TV через Alexa
Умный дом

Управление Samsung Smart TV через Alexa