JavaRush /Курсы /Модуль 3: React /Защита маршрутов с использованием react-router-dom и Auth...

Защита маршрутов с использованием react-router-dom и AuthGuard

Модуль 3: React
16 уровень , 4 лекция
Открыта

Введение

Когда пользователь заходит в ваше приложение, вы хотите быть уверены, что только авторизованные пользователи могут получить доступ к определённым частям приложения, например к панели управления или личным данным. React Router позволяет легко управлять маршрутизацией, а для ограничения доступа мы можем применить проверку состояния аутентификации пользователя. Вот здесь-то и вступает в дело защита маршрутов.

Если вы работаете с авторизацией, скорее всего, вы уже знакомы с JWT (JSON Web Token). Он подтверждает, что пользователь авторизован. AuthGuard проверяет наличие токена и решает, разрешить доступ или перенаправить пользователя на страницу входа.

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

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

Если вы ещё не установили react-router-dom, пора это сделать. Мы будем использовать версию 6, так как она более современная и удобная.

npm install react-router-dom

Теперь создадим базовую структуру маршрутов. Для этого добавим маршруты в наше приложение:

import React from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import HomePage from './pages/HomePage';
import LoginPage from './pages/LoginPage';
import DashboardPage from './pages/DashboardPage';

const App: React.FC = () => {
  return (
    <Router>
      <Routes>
        <Route path="/" element={<HomePage />} />
        <Route path="/login" element={<LoginPage />} />
        <Route path="/dashboard" element={<DashboardPage />} />
      </Routes>
    </Router>
  );
};

export default App;

Здесь мы определяем три базовых маршрута:

  • / — открытая главная страница.
  • /login — страница входа.
  • /dashboard — защищённая страница, доступная только авторизованным.

Основы AuthGuard

AuthGuard — это компонент, который проверяет, авторизован ли пользователь, и решает, позволить ему доступ к маршруту или перенаправить на страницу входа.

Создание AuthGuard

Создадим файл AuthGuard.tsx и начнем с простого компонента:

import React from 'react';
import { Navigate } from 'react-router-dom';

interface AuthGuardProps {
  children: JSX.Element;
  isAuthenticated: boolean;
}

const AuthGuard: React.FC<AuthGuardProps> = ({ children, isAuthenticated }) => {
  // Если пользователь не авторизован, перенаправляем на страницу входа
  if (!isAuthenticated) {
    return <Navigate to="/login" />;
  }

  // Если авторизован, рендерим дочерний компонент
  return children;
};

export default AuthGuard;

Обратите внимание на:

  1. props.isAuthenticated: это флаг, который указывает, авторизован ли пользователь. Его значение мы будем получать из глобального состояния или другой логики приложения.
  2. <Navigate />: компонент для перенаправления пользователя на другой маршрут.

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

Теперь мы оборачиваем защищённые маршруты компонентом AuthGuard:

import React from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import HomePage from './pages/HomePage';
import LoginPage from './pages/LoginPage';
import DashboardPage from './pages/DashboardPage';
import AuthGuard from './components/AuthGuard';

const isAuthenticated = true; // В реальном приложении этот флаг придёт из состояния пользователя

const App: React.FC = () => {
  return (
    <Router>
      <Routes>
        <Route path="/" element={<HomePage />} />
        <Route path="/login" element={<LoginPage />} />
        <Route
          path="/dashboard"
          element={
            <AuthGuard isAuthenticated={isAuthenticated}>
              <DashboardPage />
            </AuthGuard>
          }
        />
      </Routes>
    </Router>
  );
};

export default App;

Теперь, если пользователь попытается зайти на /dashboard, но не будет авторизован (то есть isAuthenticated будет false), его перенаправят на /login.

Типичные ошибки и сложности

  1. Неправильная проверка токена: часто разработчики забывают проверять срок действия JWT. Токен может быть валиден, но просрочен. Чтобы предотвратить это, вы можете кодировать время истечения в токен и проверять его перед разрешением доступа.

  2. Циклические перенаправления: если вы не учтёте сценарий, когда пользователь уже находится на странице входа и не авторизован, он может застрять в бесконечном цикле перенаправлений. Убедитесь, что вы не используете AuthGuard для маршрутов, которые должны быть открыты всем.

  3. Хранение состояния: состояние авторизации isAuthenticated часто зависит от глобального стореджа или контекста, например Redux или контекста React. Убедитесь, что используете его корректно.

Практическое применение и реальный мир

AuthGuard необходим в большинстве приложений, где требуется разделение доступа. Реальные проекты включают панели администратора, онлайн-магазины, системы управления контентом и многое другое. На собеседованиях вас практически всегда спросят про защиту маршрутов — это базовый, но крайне важный аспект любой веб-разработки.

Давайте усложним!

Чтобы сделать AuthGuard более гибким, добавим проверку ролей.

interface AuthGuardProps {
  children: JSX.Element;
  isAuthenticated: boolean;
  requiredRole?: string; // необязательное требование к роли
  userRole?: string; // роль текущего пользователя
}

const AuthGuard: React.FC<AuthGuardProps> = ({
  children,
  isAuthenticated,
  requiredRole,
  userRole,
}) => {
  if (!isAuthenticated) {
    return <Navigate to="/login" />;
  }

  if (requiredRole && userRole !== requiredRole) {
    return <Navigate to="/" />; // Перенаправляем на главную, если роль не совпадает
  }

  return children;
};

Теперь можно защитить не только маршруты для авторизации, но и маршруты, которые требуют определённой роли, например admin.

<Route
  path="/admin"
  element={
    <AuthGuard
      isAuthenticated={isAuthenticated}
      userRole="user"
      requiredRole="admin"
    >
      <AdminPage />
    </AuthGuard>
  }
/>

Теперь ваш компонент проверяет как факт аутентификации, так и соответствие роли.

Код, который вы сегодня изучили, можно легко адаптировать под любой проект. Уверены, что теперь ни один неавторизованный пользователь не проникнет в ваши защищённые маршруты!

2
Задача
Модуль 3: React, 16 уровень, 4 лекция
Недоступна
Реализация простой защиты маршрутов с помощью AuthGuard
Реализация простой защиты маршрутов с помощью AuthGuard
3
Опрос
Продвинутая аутентификация, 16 уровень, 4 лекция
Недоступен
Продвинутая аутентификация
Продвинутая аутентификация
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ