Попытка понять разницу между CanActivate и CanActivateChild

Поэтому я пытаюсь защитить доступ к нескольким маршрутам, используя охрану. Я использую следующие маршруты для этого:

const adminRoutes : Routes = [
  {
    path: 'admin',
    component: AdminComponent,
    canActivate: [ AuthGuardService ],
    children : [
      {
        path: '',
        canActivateChild: [ AuthGuardService ],
        children: [
          { path: 'edit', component: DashboardComponent},
          { path: '', component: DashboardComponent}
        ]
      }
    ]
  }
];

Вот посмотрите на что AuthGuardService похоже

import { Injectable } from '@angular/core';
import {CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot} from "@angular/router";

@Injectable()
export class AuthGuardService implements CanActivate{

  constructor(private router: Router) { }

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot){
    console.log("Guarding...");
    return this.sessionValid();
  }

  canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot){
    console.log("Guarding children...");
    return this.canActivate(route, state);
  }

  sessionValid() : boolean {
    //tests
  }

}

Когда я пытаюсь получить доступ к "/admin" и "/admin/edit" с canActivate только (canActivateChild прокомментировано) консоль отображает

Guarding...

Когда я удаляю canActivateи принести canActivateChildназад консольные дисплеи

Guarding children...

Когда я держу оба, это возвращается к отображению Guarding..., Итак, мой вопрос в том, какова цель canActivateChild когда canActivateзащищает как корневой элемент, так и детей?

PS: я понял, что canActivateChild выполняется до того, как будет активирован дочерний маршрут. Но каковы преимущества этого? Разве недостаточно одного из них?

4 ответа

Решение

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

Пример: может возникнуть ситуация, когда пользователь должен пройти аутентификацию для перехода к корневому компоненту, но должен иметь разрешение "x" для доступа к дочерним компонентам. В таких случаях, как это, canActivateChild избавляет от необходимости набирать текст canActivate охранники каждому из детей.

РЕДАКТИРОВАТЬ:

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

  {
    path: 'admin',
    component: AdminComponent,
    canActivate: [ AuthGuardService ],
    children : [
      {
        path: '', component: ...,
      },
      {
        path: 'manage-users', component: ...,
      },
      {
        path: 'manage-roles', component: ...,
      }
    ]
  }

Это должно быть защищено сверху вниз. Нет несанкционированного доступа ни к одному из маршрутов, включая root и дочерние. В этой ситуации canActivate на корневом уровне прекрасно работает, чтобы защитить все.

Но у вас также может быть время, когда у вас есть модуль Feature, где нужно охранять только определенных детей:

  {
    path: 'featureA',
    component: ...,
    canActivateChild: [ AuthGuardService ],
    children : [
      {
        path: 'manage-feature', component: ...,
      },
      {
        path: 'manage-members', component: ...,
      }
    ],
    {path: 'featureB', component: ...}
  }

В этой ситуации, возможно, всем пользователям необходимо получить доступ к корневым компонентам "featureA" и "featureB", но только определенные пользователи должны иметь возможность переходить к дочерним маршрутам "featureA". В этом случае для защиты детей проще использовать одну защиту на уровне корня, но не сам корень. Альтернативой является поставить canActivate на каждом детском маршруте охранники, которые могут стать утомительными.

Это действительно все зависит от ваших требований, но может быть неплохо иметь оба варианта canActivate а также canActivateChild,

На мой взгляд, CanActivate используется для ограничения доступа с определенного пути и всех подпутей и CanActivateChild используется для ограничения доступа к определенной группе внутри CanActivate дорожка.

Пример:

{
  path: 'admin',
  component: AdminComponent,
  canActivate: [AuthGuardService],
  children : [
    {
      path: 'books', component: ...,
    },
    {
      path: 'authors', component: ...,
    },
    {
      path: 'payments',
      canActivateChild: [AuthGuardService],
      children: [
        {
          path: 'list', component: ...
        },
        {
          path: 'list/:id', component: ...
        }
      ]
    }
  ]
}

Поскольку вам нужны два типа проверок, вы не можете иметь два canActivate методы, так что вам нужно canActivateChild для проверки разрешения внутри canActivate дорожка. Очевидно, что вы можете создать другую службу охраны (AuthGuardForChildrenRoutes) и до сих пор пользуюсь canActivate метод, но это не главное.

В этом было основное различие между canActivate и canActivatedchild,
вот ситуация, в которой можно было бы использовать эти два


Рисунок : путь для иллюстрации разницы между CanActivate и CanActivateChild CanActivate : Студент компьютерного отделения не может получить доступ к другим отделам CanActivateChild : Студент компьютерного отделения имеет доступ к компьютерному отделу (который в данном случае является родительским), но не может получить доступ к одному дочернему элементу компьютерного отдела, то есть роли преподавателя доступ



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

Другие вопросы по тегам