В библиотеке Iron маршрутизация строится вокруг декларативного
описания путей и привязки к ним метаданных, определяющих поведение
системы при переходе. Одним из ключевых механизмов ограничения доступа
выступает опция route.auth, которая позволяет встроить
проверку авторизации непосредственно в конфигурацию маршрута, не вынося
её в отдельные слои логики.
Основная идея заключается в том, что каждый маршрут может содержать правило, определяющее, имеет ли пользователь право на его посещение. Это правило может быть выражено функцией, массивом ролей, булевым флагом или асинхронной проверкой, возвращающей результат авторизации.
Типичная конфигурация маршрута в Iron выглядит как объект, где помимо пути и обработчика задаются дополнительные параметры:
const routes = [
{
path: '/dashboard',
component: Dashboard,
auth: true
}
]
Значение auth: true означает, что маршрут доступен
только авторизованным пользователям. Внутри механизма роутера это
интерпретируется как проверка состояния сессии или наличия валидного
токена.
При переходе по маршруту Iron выполняет последовательность шагов:
route.authУпрощённо логика может выглядеть так:
function canActivate(route, user) {
if (!route.auth) return true;
if (route.auth === true) return user.isAuthenticated;
return false;
}
Более гибкий подход достигается через передачу функции, позволяющей реализовать сложную логику:
{
path: '/admin',
component: AdminPanel,
auth: (user) => user && user.role === 'admin'
}
Функция получает контекст пользователя и возвращает булево значение. Это позволяет внедрять:
В реальных приложениях проверка доступа часто требует обращения к серверу. Iron поддерживает асинхронные проверки через промисы:
{
path: '/billing',
component: Billing,
auth: async (user) => {
const res = await api.checkSubscription(user.id);
return res.active;
}
}
При такой модели роутер обязан ожидать завершения проверки перед тем, как принять решение о навигации.
Ключевое поведение:
false выполняется редиректЧасто доступ определяется списком ролей. В этом случае
route.auth может быть массивом:
{
path: '/moderation',
component: ModerationPanel,
auth: ['admin', 'moderator']
}
Внутри Iron выполняется проверка принадлежности роли пользователя:
function checkRole(route, user) {
if (!Array.isArray(route.auth)) return true;
return route.auth.includes(user.role);
}
Такой подход удобен для RBAC-модели (Role-Based Access Control), где права группируются по уровням доступа.
На практике часто требуется сочетание нескольких условий. Для этого
route.auth может быть объектом:
{
path: '/settings',
component: Settings,
auth: {
roles: ['user', 'admin'],
verified: true
}
}
Логика проверки становится составной:
function complexAuth(route, user) {
const { roles, verified } = route.auth;
if (roles && !roles.includes(user.role)) return false;
if (verified && !user.verified) return false;
return true;
}
Iron определяет стандартный механизм обработки отказа:
/login, если пользователь не
авторизован/forbidden, если доступ запрещён по
ролиПример настройки:
{
path: '/admin',
component: AdminPanel,
auth: {
roles: ['admin'],
redirect: '/forbidden'
}
}
При этом роутер не просто блокирует переход, но и передаёт управление в систему навигации, сохраняя контекст попытки доступа.
Проверка route.auth почти всегда завязана на глобальное
состояние приложения. Обычно это:
Пример связки:
const user = store.getState().user;
router.beforeEach((route) => {
return canActivate(route, user);
});
При частых переходах важно избегать повторных дорогих проверок. Iron
может кешировать результат auth-функции:
Это особенно актуально при асинхронных проверках подписки или прав доступа.
Несмотря на удобство route.auth, важно учитывать, что
клиентская проверка не является полноценной защитой. Она выполняет роль
UX-ограничения, но не заменяет серверную авторизацию.
Типичная архитектура требует:
Iron поддерживает обновление маршрутов в рантайме. Это позволяет
менять route.auth без перезагрузки приложения:
router.updateRoute('/admin', {
auth: (user) => user.permissions.includes('admin_access')
});
Такой подход применяется в:
При использовании вложенных маршрутов возможно наследование правил:
{
path: '/admin',
auth: ['admin'],
children: [
{
path: '/admin/users',
component: Users
}
]
}
Если дочерний маршрут не содержит собственного auth, он
наследует правило родителя. Это уменьшает дублирование конфигурации и
снижает вероятность ошибок в безопасности.
Типичные проблемы при работе с доступом:
Корректная архитектура требует централизованной обработки
auth, а не распределения проверок по UI-компонентам.
Если пользователь выходит из системы во время активной сессии, Iron должен реагировать на это:
store.subscribe((state) => {
if (!state.user) {
router.invalidateAuthCache();
router.navigate('/login');
}
});
Механизм route.auth в Iron формирует слой декларативной
безопасности маршрутов, который объединяет:
При грамотной архитектуре он становится центральной точкой контроля навигации, снижая сложность компонентов и повышая предсказуемость поведения приложения.