Введение
Когда пользователь заходит в ваше приложение, вы хотите быть уверены, что только авторизованные пользователи могут получить доступ к определённым частям приложения, например к панели управления или личным данным. 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;
Обратите внимание на:
props.isAuthenticated: это флаг, который указывает, авторизован ли пользователь. Его значение мы будем получать из глобального состояния или другой логики приложения.<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.
Типичные ошибки и сложности
Неправильная проверка токена: часто разработчики забывают проверять срок действия JWT. Токен может быть валиден, но просрочен. Чтобы предотвратить это, вы можете кодировать время истечения в токен и проверять его перед разрешением доступа.
Циклические перенаправления: если вы не учтёте сценарий, когда пользователь уже находится на странице входа и не авторизован, он может застрять в бесконечном цикле перенаправлений. Убедитесь, что вы не используете AuthGuard для маршрутов, которые должны быть открыты всем.
Хранение состояния: состояние авторизации
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>
}
/>
Теперь ваш компонент проверяет как факт аутентификации, так и соответствие роли.
Код, который вы сегодня изучили, можно легко адаптировать под любой проект. Уверены, что теперь ни один неавторизованный пользователь не проникнет в ваши защищённые маршруты!
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ