경로 가드에 매개 변수 전달
나는 이러한 역할을 기반으로 앱의 일부에 대한 탐색을 차단하기 위해 가드를 사용해야하는 많은 역할이있는 앱을 작업 중입니다. 각 역할에 대해 개별 가드 클래스를 만들 수 있지만 어떻게 든 매개 변수를 전달할 수있는 하나의 클래스를 갖고 싶습니다. 즉, 다음과 유사한 작업을 수행하고 싶습니다.
{
path: 'super-user-stuff',
component: SuperUserStuffComponent,
canActivate: [RoleGuard.forRole('superUser')]
}
그러나 당신이 통과하는 것은 경비원의 유형 이름이기 때문에 그렇게 할 방법을 생각할 수 없습니다. 총알을 깨고 역할별로 개별 가드 클래스를 작성하고 대신 단일 매개 변수화 된 유형을 갖는 것에 대한 내 우아함을 깨뜨려야할까요?
당신은 이것을해야합니다.
를 사용하는 대신 forRole()
다음을 사용해야합니다.
{
path: 'super-user-stuff',
component: SuperUserStuffComponent,
canActivate: RoleGuard,
data: {roles: ['SuperAdmin', ...]}
}
RoleGuard에서 이것을 사용하십시오.
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot)
: Observable<boolean> | Promise<boolean> | boolean {
let roles = route.data.roles as Array<string>;
...
}
여기에 내 생각과 누락 된 공급자 문제에 대한 가능한 해결책이 있습니다.
제 경우에는 권한 또는 권한 목록을 매개 변수로 취하는 가드가 있지만 역할이있는 것도 마찬가지입니다.
허가 유무에 관계없이 인증 가드를 다루는 클래스가 있습니다.
@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 = [ ];
Then we can use this array to register all guards - this is ok as long as we make sure that by the time the app module registers these providers, the routes had been defined and all the guard classes had been created (e.g. check import order and keep these providers as low as possible in the list - having a routing module helps):
providers: [
// ...
AuthGuardService,
...AuthGuardService.guards,
]
Hope this helps.
@AluanHaddad's solution is giving "no provider" error. Here is a fix for that (it feels dirty, but I lack the skills to make a better one).
Conceptually, I register, as a provider, each dynamically generated class created by roleGuard
.
So for every role checked:
canActivate: [roleGuard('foo')]
you should have:
providers: [roleGuard('foo')]
However, @AluanHaddad's solution as-is will generate new class for each call to roleGuard
, even if roles
parameter is the same. Using lodash.memoize
it looks like this:
export var roleGuard = _.memoize(function forRole(...roles: string[]): Type<CanActivate> {
return class AuthGuard implements CanActivate {
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):
Observable<boolean>
| Promise<boolean>
| boolean {
console.log(`checking access for ${roles.join(', ')}.`);
return true;
}
}
});
Note, each combination of roles generates a new class, so you need to register as a provider every combination of roles. I.e. if you have:
canActivate: [roleGuard('foo')]
and canActivate: [roleGuard('foo', 'bar')]
you will have to register both: providers[roleGuard('foo'), roleGuard('foo', 'bar')]
A better solution would be to register providers automatically in a global providers collection inside roleGuard
, but as I said, I lack the skills to implement that.
참고URL : https://stackoverflow.com/questions/42719445/pass-parameter-into-route-guard
'Programing' 카테고리의 다른 글
콘솔에 인쇄 된 문자를 지우는 방법 (0) | 2020.11.04 |
---|---|
OS X 10.8 업그레이드 후 Python pip가 손상됨 (0) | 2020.11.04 |
Type의 기본 생성자를 얻는 가장 효율적인 방법 (0) | 2020.11.04 |
WPF 명령 새로 고침 (0) | 2020.11.04 |
정밀도 수준이 다른 Date 객체 비교 (0) | 2020.11.04 |