这是我对此的看法以及缺少提供程序问题的可能解决方案。
在我的例子中,我们有一个将权限或权限列表作为参数的守卫,但它具有相同的角色。
我们有一个类可以在有或没有许可的情况下处理身份验证守卫:
@Injectable()
export class AuthGuardService implements CanActivate {
checkUserLoggedIn() { ... }
这涉及检查用户活动会话等。
其中还包含一个用于获取自定义权限守卫的方法,这个方法其实是依赖于AuthGuardService本身
static forPermissions(permissions: string | string[]) {
@Injectable()
class AuthGuardServiceWithPermissions {
constructor(private authGuardService: AuthGuardService) { } // uses the parent class instance actually, but could in theory take any other deps
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
// checks typical activation (auth) + custom permissions
return this.authGuardService.canActivate(route, state) && this.checkPermissions();
}
checkPermissions() {
const user = ... // get the current user
// checks the given permissions with the current user
return user.hasPermissions(permissions);
}
}
AuthGuardService.guards.push(AuthGuardServiceWithPermissions);
return AuthGuardServiceWithPermissions;
}
这允许我们使用该方法在我们的路由模块中根据权限参数注册一些自定义守卫:
....
{ path: 'something',
component: SomeComponent,
canActivate: [ AuthGuardService.forPermissions('permission1', 'permission2') ] },
forPermission 的有趣部分是AuthGuardService.guards.push - 这基本上可以确保在任何时候调用forPermissions 来获取自定义保护类,它也会将其存储在这个数组中。这在主类上也是静态的:
public static guards = [ ];
然后我们可以使用这个数组来注册所有的守卫——这是可以的,只要我们确保在应用模块注册这些提供者时,路由已经被定义并且所有的守卫类都已经被创建(例如检查导入顺序并让这些提供程序在列表中尽可能低 - 有一个路由模块会有所帮助):
providers: [
// ...
AuthGuardService,
...AuthGuardService.guards,
]
希望这会有所帮助。