Редиректы для неавторизованных

В библиотеке Navigo маршрутизация строится на принципе сопоставления URL с обработчиками и компонентами. Для приложений с авторизацией часто требуется ограничить доступ к определённым маршрутам и перенаправлять неавторизованных пользователей на страницу входа. Реализация такой логики включает несколько ключевых этапов: проверку состояния авторизации, использование промежуточных функций (middleware) и настройку редиректов.


Проверка авторизации

Перед тем как настраивать редиректы, необходимо определить способ проверки авторизации. Чаще всего для этого используется токен в localStorage, sessionStorage или состояние в глобальном объекте приложения:

function isAuthenticated() {
  return Boolean(localStorage.getItem('authToken'));
}

Эта функция возвращает true, если пользователь авторизован, и false, если нет. Именно на её основе будет приниматься решение о редиректе.


Использование before для маршрутов

В Navigo можно использовать метод before для проверки условий перед вызовом обработчика маршрута. Он принимает коллбэк с аргументами done и params, где done необходимо вызвать, чтобы продолжить навигацию:

const router = new Navigo('/', { hash: true });

router.on('/dashboard', {
  before: (done, params) => {
    if (!isAuthenticated()) {
      router.navigate('/login'); // редирект на страницу входа
    } else {
      done(); // разрешаем доступ
    }
  },
  uses: () => {
    renderDashboard();
  }
});

router.on('/login', () => {
  renderLogin();
});

router.resolve();

Ключевой момент: использование before позволяет перехватывать попытку перехода на маршрут до вызова его основного обработчика, что делает редирект безопасным и предсказуемым.


Глобальные перехватчики

Если приложение содержит множество защищённых маршрутов, можно создать глобальный перехватчик с проверкой авторизации для всех маршрутов одновременно:

router.hooks({
  before: (done, params, current) => {
    const protectedRoutes = ['/dashboard', '/profile', '/settings'];
    if (protectedRoutes.includes(current.url) && !isAuthenticated()) {
      router.navigate('/login');
    } else {
      done();
    }
  }
});

Такой подход снижает дублирование кода, поскольку проверка авторизации происходит централизованно, и все защищённые маршруты автоматически используют один и тот же механизм редиректа.


Передача исходного URL для пост-логина

Часто требуется, чтобы после авторизации пользователь возвращался на страницу, которую пытался открыть. Для этого можно добавлять параметр redirect:

router.on('/dashboard', {
  before: (done, params) => {
    if (!isAuthenticated()) {
      const redirectUrl = encodeURIComponent('/dashboard');
      router.navigate(`/login?redirect=${redirectUrl}`);
    } else {
      done();
    }
  },
  uses: () => renderDashboard()
});

router.on('/login', () => {
  renderLogin();

  const urlParams = new URLSearchParams(window.location.search);
  const redirect = urlParams.get('redirect');
  
  document.querySelector('#loginForm').addEventListener('submit', (e) => {
    e.preventDefault();
    authenticateUser(); // логика авторизации
    if (redirect) {
      router.navigate(decodeURIComponent(redirect));
    } else {
      router.navigate('/');
    }
  });
});

Выделение ключевого момента: использование параметра redirect позволяет сохранить UX-поток, обеспечивая возврат пользователя на исходную защищённую страницу после успешного входа.


Динамические маршруты и проверка доступа

Для маршрутов с динамическими сегментами (/profile/:id) логика редиректа также может применяться:

router.on('/profile/:id', {
  before: (done, params) => {
    if (!isAuthenticated()) {
      router.navigate(`/login?redirect=/profile/${params.id}`);
    } else {
      done();
    }
  },
  uses: (params) => renderProfile(params.id)
});

Важно: params в before доступны сразу и позволяют формировать корректный URL для редиректа.


Настройка редиректа при 404

Navigo поддерживает обработку несуществующих маршрутов. Для защиты неавторизованных пользователей можно комбинировать редирект и страницу “не найдено”:

router.notFound(() => {
  if (!isAuthenticated()) {
    router.navigate('/login');
  } else {
    renderNotFound();
  }
});

Таким образом, даже попытка открыть несуществующую страницу у неавторизованного пользователя приведёт его на страницу входа.


Выводы по организации редиректов

  • Функция проверки авторизации является основой всех редиректов.
  • Метод before для отдельных маршрутов позволяет гибко управлять доступом.
  • Глобальные hooks уменьшают дублирование кода при множественных защищённых маршрутах.
  • Параметр redirect сохраняет путь пользователя для пост-логина, улучшая UX.
  • Динамические маршруты и notFound интегрируются с общей системой проверки доступа, обеспечивая предсказуемое поведение навигации.

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