所以,我试图通过使用警卫来保护对多条路线的访问。我正在使用以下路由来执行此操作:
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
}
}
当我尝试仅使用canActivate
访问'/ admin'和'/ admin / edit'时(canActivateChild
被注释)控制台显示
Guarding...
当我删除canActivate
and带canActivateChild
back控制台显示
Guarding children...
当我保留两者时,它会回到显示Guarding...
。所以,我的问题是当canActivateChild
p保护根元素和孩子时,有canActivate
的目的是什么?
PS:我知道canActivateChild
在子路线被激活之前运行。但那有什么好处呢?是不是只保留其中一个?
两者都很重要,因为您可能有不同的要求,用户可以访问根组件,但可能不满足子组件的条件。
示例:您可能遇到必须通过身份验证才能导航到根组件的情况,但必须具有权限“x”才能访问子组件。在这种情况下,canActivateChild
可以节省大量的打字,因为必须为每个孩子添加canActivate
防护。
编辑:
例如,您可能有一个管理模块,其中所有路由都需要防止未经授权的进入:
{
path: 'admin',
component: AdminComponent,
canActivate: [ AuthGuardService ],
children : [
{
path: '', component: ...,
},
{
path: 'manage-users', component: ...,
},
{
path: 'manage-roles', component: ...,
}
]
}
这需要从上到下保护。未经授权访问任何路由,包括root和children。在这种情况下,根级别的canActivate
可以很好地保护一切。
但是,您可能还有一些功能模块,其中只需要保护某些孩子:
{
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
路径内的permision。显然,你可以创建一个不同的守卫服务(AuthGuardForChildrenRoutes
),仍然使用canActivate
方法,但这不是重点。
在您的示例中,您在canActivateChild中调用了canActivate,因此当您在子路径之间遍历时,两个警卫都会被调用。如果您在两个警卫中都有不同的身份验证逻辑,那么在子路径之间遍历时,您的canActivate警卫将不会执行。