Защищённые маршруты (protected routes) позволяют ограничивать доступ к определённым страницам приложения, обеспечивая контроль над тем, какие пользователи могут просматривать конкретный контент. В Page.js это реализуется через комбинацию маршрутизации и проверки состояния пользователя, чаще всего авторизации.
Page.js работает на основе клиентской маршрутизации, где каждая функция-обработчик маршрута получает объект контекста, содержащий URL, параметры и состояние. Использование защищённых маршрутов предполагает проверку состояния пользователя перед выполнением перехода.
import page from 'page';
// Определение публичного маршрута
page('/', () => {
console.log('Главная страница');
});
// Определение маршрута входа
page('/login', () => {
console.log('Страница входа');
});
В этом примере маршруты доступны всем пользователям. Для защищённых маршрутов необходимо добавить проверку авторизации.
Для контроля доступа создаётся middleware — промежуточная функция, которая выполняется перед основным обработчиком маршрута.
function requireAuth(ctx, next) {
const isAuthenticated = Boolean(localStorage.getItem('token'));
if (isAuthenticated) {
next(); // пользователь авторизован, продолжаем
} else {
page('/login'); // перенаправляем на страницу входа
}
}
Здесь requireAuth проверяет наличие токена в
localStorage. Если токен отсутствует, пользователь
автоматически перенаправляется на страницу логина. Если токен
присутствует — вызывается next(), позволяя обработчику
маршрута выполняться дальше.
Middleware можно подключать как к отдельным маршрутам, так и к группе маршрутов:
// Защищённый маршрут
page('/dashboard', requireAuth, () => {
console.log('Панель пользователя');
});
// Ещё один защищённый маршрут
page('/profile', requireAuth, () => {
console.log('Профиль пользователя');
});
Page.js обрабатывает маршруты последовательно. Сначала вызывается
middleware requireAuth, и только при успешной проверке
выполняется функция рендеринга страницы.
Если несколько маршрутов требуют одинаковой проверки, удобнее создавать группы маршрутов:
function protectedRoute(route, handler) {
page(route, requireAuth, handler);
}
protectedRoute('/settings', () => {
console.log('Настройки пользователя');
});
protectedRoute('/account', () => {
console.log('Управление аккаунтом');
});
Такой подход упрощает поддержку и масштабирование приложения, предотвращая дублирование проверок авторизации.
В реальных приложениях авторизация часто требует обращения к серверу, чтобы подтвердить токен или права доступа. Middleware легко адаптируется под асинхронные операции:
async function requireAuthAsync(ctx, next) {
try {
const token = localStorage.getItem('token');
const response = await fetch('/api/validate-token', {
headers: { 'Authorization': `Bearer ${token}` }
});
if (response.ok) {
next();
} else {
page('/login');
}
} catch (error) {
page('/login');
}
}
page('/dashboard', requireAuthAsync, () => {
console.log('Панель пользователя с асинхронной проверкой');
});
Асинхронная проверка позволяет удостовериться, что токен действителен и пользователь имеет соответствующие права перед рендерингом контента.
Для гибкой работы с защищёнными маршрутами полезно хранить состояние авторизации в централизованном хранилище (например, Redux или простой объект):
const auth = {
isAuthenticated: false,
login(token) {
localStorage.setItem('token', token);
this.isAuthenticated = true;
},
logout() {
localStorage.removeItem('token');
this.isAuthenticated = false;
}
};
function requireAuthWithState(ctx, next) {
if (auth.isAuthenticated) {
next();
} else {
page('/login');
}
}
page('/dashboard', requireAuthWithState, () => {
console.log('Панель пользователя с контролем через состояние');
});
Такое решение позволяет динамически менять доступность маршрутов без
постоянной проверки localStorage.
Часто требуется вернуть пользователя на защищённый маршрут после авторизации. Для этого сохраняется целевой URL:
let redirectTo = '/';
function requireAuth(ctx, next) {
if (auth.isAuthenticated) {
next();
} else {
redirectTo = ctx.path;
page('/login');
}
}
// После успешного входа
function loginSuccess() {
auth.login('example-token');
page(redirectTo);
}
Такой подход улучшает пользовательский опыт и обеспечивает плавную навигацию.
Page.js поддерживает динамические сегменты URL, что полезно для защищённых страниц профиля или деталей ресурса:
page('/profile/:userId', requireAuth, (ctx) => {
console.log(`Профиль пользователя с ID: ${ctx.params.userId}`);
});
Middleware requireAuth срабатывает перед обработчиком,
обеспечивая безопасность даже при динамических URL.
Эти инструменты в комбинации позволяют создавать надёжные и масштабируемые защищённые маршруты в Page.js, обеспечивая плавную и безопасную клиентскую навигацию.