Защита групп маршрутов

Группировка маршрутов

Vue Router позволяет структурировать маршруты в виде групп, что особенно полезно для управления доступом и организации больших приложений. Группы маршрутов создаются через массив children у родительского маршрута. Это дает возможность задавать общие свойства для нескольких маршрутов, включая guards, meta-поля и параметры.

Пример структуры группы маршрутов:

const routes = [
  {
    path: '/admin',
    component: AdminLayout,
    children: [
      { path: 'dashboard', component: Dashboard },
      { path: 'users', component: Users },
      { path: 'settings', component: Settings }
    ]
  }
]

Здесь маршруты /admin/dashboard, /admin/users и /admin/settings образуют группу, объединённую общим родителем /admin. Это позволяет централизованно управлять поведением всех вложенных маршрутов.

Использование meta для контроля доступа

Для защиты маршрутов используется свойство meta, которое позволяет хранить дополнительную информацию, например, флаги авторизации или роли пользователя. Каждому маршруту можно добавить ключ requiresAuth:

const routes = [
  {
    path: '/admin',
    component: AdminLayout,
    meta: { requiresAuth: true },
    children: [
      { path: 'dashboard', component: Dashboard },
      { path: 'users', component: Users },
      { path: 'settings', component: Settings }
    ]
  }
]

Теперь все дочерние маршруты наследуют этот флаг, что упрощает проверку прав доступа.

Глобальные навигационные охранники

Vue Router предоставляет глобальные навигационные охранники, которые позволяют перехватывать попытки перехода между маршрутами и реализовывать проверки:

router.beforeEach((to, from, next) => {
  const requiresAuth = to.matched.some(record => record.meta.requiresAuth);
  const userIsAuthenticated = store.getters.isAuthenticated;

  if (requiresAuth && !userIsAuthenticated) {
    next({ path: '/login', query: { redirect: to.fullPath } });
  } else {
    next();
  }
});

Ключевое здесь — метод to.matched.some(), который проверяет все маршруты в цепочке, включая родительские, что позволяет легко защитить все маршруты группы через один флаг.

Локальные навигационные охранники

Для более точечного контроля можно использовать локальные охранники у конкретного маршрута:

const routes = [
  {
    path: '/admin',
    component: AdminLayout,
    beforeEnter: (to, from, next) => {
      const userRole = store.getters.userRole;
      if (userRole !== 'admin') {
        next('/not-authorized');
      } else {
        next();
      }
    },
    children: [
      { path: 'dashboard', component: Dashboard },
      { path: 'users', component: Users }
    ]
  }
]

beforeEnter применяется только к указанному маршруту и его дочерним маршрутам, что позволяет реализовать защиту конкретной группы без глобального вмешательства.

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

Vue Router позволяет реализовать динамическую проверку доступа, используя meta поля с ролями:

const routes = [
  {
    path: '/admin',
    component: AdminLayout,
    meta: { roles: ['admin', 'manager'] },
    children: [
      { path: 'dashboard', component: Dashboard },
      { path: 'users', component: Users }
    ]
  }
];

Навигационный охранник проверяет роли пользователя:

router.beforeEach((to, from, next) => {
  const requiredRoles = to.matched
    .flatMap(record => record.meta.roles || []);
  
  const userRole = store.getters.userRole;

  if (requiredRoles.length && !requiredRoles.includes(userRole)) {
    next('/not-authorized');
  } else {
    next();
  }
});

Такой подход позволяет гибко управлять доступом к целым группам маршрутов на основе пользовательских ролей.

Применение вложенных охранников

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

const routes = [
  {
    path: '/admin',
    component: AdminLayout,
    meta: { requiresAuth: true },
    children: [
      {
        path: 'dashboard',
        component: Dashboard
      },
      {
        path: 'users',
        component: Users,
        meta: { roles: ['admin'] }
      }
    ]
  }
];

Глобальный охранник проверяет авторизацию, а отдельный дочерний meta.roles проверяется локально или через дополнительный глобальный обработчик.

Редиректы и fallback маршруты

Для группы маршрутов часто задают редиректы или маршрут fallback:

const routes = [
  {
    path: '/admin',
    component: AdminLayout,
    redirect: '/admin/dashboard',
    children: [
      { path: 'dashboard', component: Dashboard },
      { path: 'users', component: Users },
      { path: 'settings', component: Settings }
    ]
  }
];

Если пользователь заходит на /admin без указания дочернего маршрута, происходит автоматический переход на /admin/dashboard. Это улучшает UX и упрощает контроль доступа, так как редирект учитывает охранники маршрутов.

Ключевые моменты

  • children позволяет создавать группы маршрутов с общими настройками.
  • meta — основной способ хранения информации для проверки доступа.
  • to.matched используется для проверки всех маршрутов в цепочке.
  • Глобальные и локальные охранники могут сочетаться для гибкой защиты.
  • Редиректы и fallback маршруты упрощают навигацию внутри группы.

Эта схема обеспечивает централизованное управление безопасностью, упрощает поддержку и масштабирование маршрутов в больших Vue-приложениях.