Защищенные маршруты — это маршруты, доступ к которым ограничен определенными условиями, чаще всего аутентификацией пользователя или проверкой его прав. В TanStack Router концепция защиты маршрутов строится на использовании проверок загрузчиков данных (loader functions) и хуков перехода (navigation hooks), что позволяет централизованно контролировать доступ к различным частям приложения.
Для начала необходимо определить маршрут с ограниченным доступом. В
TanStack Router маршруты создаются через функцию
createRoute, где можно указать путь, компонент и функции
для проверки доступа:
import { createRoute } from '@tanstack/router';
import { requireAuth } from './auth';
const protectedRoute = createRoute({
path: '/dashboard',
component: DashboardPage,
loader: async ({ context }) => {
await requireAuth(context.user);
},
});
Ключевые моменты:
loader выполняется перед рендером компонента.loader можно бросать ошибки
(throw new Error) или перенаправлять пользователя
(redirect('/login')) в случае отсутствия доступа.Для повторного использования проверок удобно создавать отдельные функции проверки, которые можно использовать в нескольких маршрутах:
export async function requireAuth(user) {
if (!user || !user.isAuthenticated) {
throw redirect('/login');
}
}
export async function requireAdmin(user) {
if (!user || !user.isAdmin) {
throw redirect('/unauthorized');
}
}
Затем эти функции подключаются в соответствующих loader
маршрутах:
const adminRoute = createRoute({
path: '/admin',
component: AdminPage,
loader: async ({ context }) => {
await requireAdmin(context.user);
},
});
TanStack Router поддерживает вложенные маршруты, что позволяет применять защиту не на каждом маршруте, а на группе маршрутов:
const protectedGroup = createRoute({
path: '/app',
loader: async ({ context }) => {
await requireAuth(context.user);
},
children: [
createRoute({ path: 'profile', component: ProfilePage }),
createRoute({ path: 'settings', component: SettingsPage }),
],
});
В этом примере пользователь должен быть аутентифицирован, чтобы
получить доступ к любой странице внутри /app.
TanStack Router предоставляет хуки для контроля навигации:
onEnter и onLeave могут использоваться для
динамической проверки прав пользователя и блокировки перехода при
необходимости:
protectedRoute.onEnter(({ context }) => {
if (!context.user.isAuthenticated) {
return redirect('/login');
}
});
Таким образом, проверка выполняется не только при первоначальной загрузке маршрута, но и при попытке перехода через внутреннюю навигацию приложения.
TanStack Router позволяет обрабатывать ошибки и перенаправления,
возникающие в loader, с помощью специального маршрута
ошибок:
const rootRoute = createRoute({
path: '/',
component: RootPage,
errorComponent: ErrorPage,
children: [protectedRoute, adminRoute],
});
loader автоматически передаются в
errorComponent.redirect позволяет мгновенно перенаправить пользователя
без отображения компонента ошибки.loader позволяет интегрировать проверку с сервером,
токенами и внешними API.errorComponent и redirect обеспечивает
корректное поведение при нарушении условий доступа.const appRoutes = createRoute({
path: '/',
component: AppLayout,
children: [
createRoute({ path: 'login', component: LoginPage }),
createRoute({
path: 'dashboard',
loader: async ({ context }) => await requireAuth(context.user),
component: DashboardPage,
}),
createRoute({
path: 'admin',
loader: async ({ context }) => await requireAdmin(context.user),
component: AdminPage,
}),
],
});
В данной конфигурации:
/login./dashboard доступна только аутентифицированным
пользователям./admin доступна только пользователям с правами
администратора.errorComponent.