Guard-функции

Guard-функции в библиотеке Navigo — это специальные функции, позволяющие контролировать доступ к определённым маршрутам. Они выполняются перед обработкой маршрута и могут предотвратить переход на страницу, если определённые условия не выполнены. Это особенно полезно для реализации авторизации, проверки состояния приложения или динамического управления доступом.


Синтаксис Guard-функций

Guard-функция регистрируется вместе с маршрутом или группой маршрутов и имеет следующий базовый синтаксис:

const router = new Navigo('/');

router.on('/dashboard', {
  uses: () => {
    console.log('Маршрут доступен');
  },
  guard: (params, route) => {
    // Возвращаем true для разрешения перехода
    // Возвращаем false для блокировки
  }
});

Параметры функции guard:

  1. params — объект с параметрами маршрута, например :id в /user/:id.
  2. route — объект маршрута, содержащий его путь и дополнительные настройки.

Guard-функция должна возвращать булево значение:

  • true — разрешает переход.
  • false — блокирует переход, оставляя пользователя на текущем маршруте.

Асинхронные guard-функции

Guard-функции в Navigo поддерживают асинхронный код. Это позволяет, например, проверять права пользователя через API:

router.on('/profile', {
  uses: () => {
    console.log('Профиль открыт');
  },
  guard: async (params, route) => {
    const response = await fetch('/api/check-auth');
    const data = await response.json();
    return data.isAuthorized;
  }
});

Если возвращаемое значение промиса будет false, Navigo автоматически отменяет переход.


Guard на уровне группы маршрутов

Navigo позволяет задавать guard для группы маршрутов. Это экономит код, если несколько страниц требуют одинаковых проверок:

router.on({
  '/settings': settingsHandler,
  '/settings/account': accountHandler
}, {
  guard: (params, route) => {
    return localStorage.getItem('token') !== null;
  }
});

В данном примере доступ к маршрутам /settings и /settings/account разрешён только авторизованным пользователям.


Передача контекста в guard

Guard-функции могут использовать внешние переменные или состояние приложения:

let isLoggedIn = false;

router.on('/dashboard', {
  uses: dashboardHandler,
  guard: (params, route) => isLoggedIn
});

Изменяя значение isLoggedIn, можно динамически контролировать доступ к маршруту без необходимости перестраивать маршруты.


Взаимодействие guard с before и after хуками

Guard-функции выполняются до хука before. Это позволяет:

  1. Блокировать переход сразу, не выполняя дополнительных действий.
  2. Использовать before только для предварительной подготовки страницы, если guard пропустил переход.

Пример:

router.on('/dashboard', {
  uses: dashboardHandler,
  guard: () => isUserAdmin,
  before: () => console.log('Подготовка данных')
});

Если isUserAdmin равно false, before не будет вызван.


Рекомендации по использованию guard

  • Минимизировать время выполнения: guard-функции должны работать быстро, чтобы не задерживать переход.
  • Возврат булевого значения: строго использовать true или false либо промис, который резолвится в булево.
  • Логирование и отладка: удобно выводить в консоль route и params для отслеживания причин блокировки.
  • Комбинирование с маршрутными параметрами: guard может проверять конкретные параметры, например, доступ к /user/:id только для текущего пользователя.

Примеры реального использования

Защита страниц авторизацией:

router.on('/admin', {
  uses: adminHandler,
  guard: () => !!localStorage.getItem('adminToken')
});

Проверка ролей пользователя:

router.on('/editor', {
  uses: editorHandler,
  guard: (params) => userRole === 'editor' || userRole === 'admin'
});

Редирект при блокировке:

router.on('/premium', {
  uses: premiumHandler,
  guard: () => {
    if (!hasPremiumAccess) {
      router.navigate('/subscribe');
      return false;
    }
    return true;
  }
});

Guard-функции в Navigo обеспечивают гибкий контроль маршрутов, позволяя строить динамические и безопасные интерфейсы без сложных обёрток и дополнительного состояния. Они полностью интегрируются с асинхронным кодом и системой групп маршрутов, делая библиотеку мощным инструментом для SPA.