Попытка понять разницу между 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 не будет выполняться при обходе дочерних маршрутов.