В React Router редирект представляет собой автоматическую навигацию
пользователя с одного маршрута на другой. Основными инструментами для
этого являются компоненты <Navigate> (в версиях v6+)
и функции программной навигации useNavigate(). Ключевой
момент — редирект должен быть предсказуемым и безопасным, чтобы избежать
непреднамеренного перехода на сторонние ресурсы или бесконечных циклов
навигации.
import { Navigate } from "react-router-dom";
function ProtectedPage({ isAuthenticated }) {
if (!isAuthenticated) {
return <Navigate to="/login" replace />;
}
return <div>Контент защищенной страницы</div>;
}
Разбор ключевых моментов:
replace предотвращает создание лишней истории
переходов в браузере, что особенно важно для редиректов после успешной
авторизации или выхода.<Navigate> вместо
window.location сохраняет преимущества SPA (Single Page
Application), предотвращая полное обновление страницы.Функция useNavigate() позволяет управлять переходами
динамически:
import { useNavigate } from "react-router-dom";
function LoginButton({ isAuthenticated }) {
const navigate = useNavigate();
const handleLogin = () => {
// Проверка данных пользователя
if (isAuthenticated) {
navigate("/dashboard", { replace: true });
}
};
return <button onCl ick={handleLogin}>Войти</button>;
}
Безопасность: важно проверять, что путь назначения является допустимым маршрутом внутри приложения. Никогда не использовать пользовательский ввод напрямую для формирования пути редиректа, чтобы исключить уязвимости открытых редиректов.
Открытые редиректы — ситуация, когда злоумышленник может подставить произвольный URL, и пользователь будет перенаправлен на сторонний ресурс. В React Router защита реализуется через проверку разрешённых маршрутов:
const allowedPaths = ["/dashboard", "/profile", "/settings"];
function SafeRedirect({ target }) {
if (!allowedPaths.includes(target)) {
return <Navigate to="/404" replace />;
}
return <Navigate to={target} replace />;
}
Рекомендации по безопасной работе с редиректами:
<a> с атрибутами
rel="noopener noreferrer" target="_blank" вместо редиректа
через React Router.Частая задача — вернуть пользователя на страницу, с которой он
пытался попасть на защищённый контент. Для этого удобно сохранять
изначальный путь в состоянии маршрутизатора или в
location.state:
import { useLocation, Navigate } from "react-router-dom";
function LoginPage({ isAuthenticated }) {
const location = useLocation();
const from = location.state?.from?.pathname || "/dashboard";
if (isAuthenticated) {
return <Navigate to={from} replace />;
}
return <div>Форма авторизации</div>;
}
Особенности:
location.state.from используется для безопасного
возврата на предыдущий маршрут.replace предотвращает добавление страницы
логина в историю после успешного входа.Циклический редирект возникает, если маршрут постоянно перенаправляет пользователя обратно на сам себя. В React Router для предотвращения таких ситуаций рекомендуется:
function AuthRedirect({ isAuthenticated }) {
const location = useLocation();
if (!isAuthenticated && location.pathname !== "/login") {
return <Navigate to="/login" replace />;
}
return <div>Защищённый контент</div>;
}
Для безопасной работы с редиректами в React Router нужно учитывать несколько ключевых правил:
replace для редиректов после действий,
связанных с авторизацией.Эти подходы обеспечивают безопасное, предсказуемое и удобное управление навигацией в приложениях на React Router.