파라미터를 루트 가드에 전달합니다.
저는 많은 역할을 하는 앱을 만들고 있는데, 그 역할에 따라 앱의 일부에 대한 네비게이션을 차단하기 위해 가드를 사용해야 합니다.각 역할에 대해 개별 가드 클래스를 만들 수 있지만, 어떤 식으로든 매개 변수를 전달할 수 있는 클래스를 하나 갖고 싶습니다.즉, 다음과 같은 일을 할 수 있으면 좋겠습니다.
{
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;
}
이를 통해 라우팅 모듈의 permission 파라미터에 따라 커스텀가드를 등록할 수 있습니다.
....
{ path: 'something',
component: SomeComponent,
canActivate: [ AuthGuardService.forPermissions('permission1', 'permission2') ] },
의 흥미로운 부분은forPermission
이AuthGuardService.guards.push
- 기본적으로는, 언제라도,forPermissions
커스텀 가드클래스를 취득하기 위해서 호출됩니다.이 클래스도 이 배열에 저장됩니다.이것은 메인 클래스에서도 스태틱합니다.
public static guards = [ ];
그런 다음 이 어레이를 사용하여 모든 가드를 등록할 수 있습니다.앱 모듈이 이러한 프로바이더를 등록할 때 루트가 정의되고 모든 가드 클래스가 생성되었는지 확인하기만 하면 됩니다(예를 들어 Import 순서를 확인하고 목록에서 이러한 프로바이더를 가능한 낮게 유지하는 등 라우팅 모듈이 도움이 됩니다).
providers: [
// ...
AuthGuardService,
...AuthGuardService.guards,
]
이게 도움이 됐으면 좋겠다.
다른 옵션 조합의 접근방식은data
및 공장 기능:
export function canActivateForRoles(roles: Role[]) {
return {data: {roles}, canActivate: [RoleGuard]}
}
export class RoleGuard implements CanActivate {
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot)
: Observable<boolean> | Promise<boolean> | boolean {
const roles = route.data.roles as Role[];
...
}
}
...
{ path: 'admin', component: AdminComponent, ...canActivateWithRoles([Role.Admin]) },
롤가드는 다음과 같이 쓸 수 있습니다.
export class RoleGuard {
static forRoles(...roles: string[]) {
@Injectable({
providedIn: 'root'
})
class RoleCheck implements CanActivate {
constructor(private authService: AuthService) { }
canActivate(): Observable<boolean> | Promise<boolean> | boolean {
const userRole = this.authService.getRole();
return roles.includes(userRole);
}
}
return RoleCheck;
}
}
또한 다음과 같이 여러 역할과 함께 사용할 수 있습니다.
{
path: 'super-user-stuff',
component: SuperUserStuffComponent,
canActivate: [RoleGuard.forRoles('superUser', 'admin', 'superadmin')]
}
2022년부터는 CanActivateFn(https://angular.io/api/router/CanActivateFn)을 사용할 수 있습니다.이 함수는 CanActivateFn 인스턴스를 반환합니다.
// Returns a function which can act as a guard for a route
function requireAnyRole(...roles: Role[]): CanActivateFn {
return (ars: ActivatedRouteSnapshot, rss: RouterStateSnapshot) => {
// do some checks here and return true/false/observable
// can even inject stuff with inject(ClassOrToken)
}
}
루트를 정의할 때 사용할 수 있습니다.
{
path: 'some/path',
component: WhateverComponent,
canActivate: [requireAnyRole(Role1, Role2, Role3)]
}
@AluanHaddad의 솔루션이 "공급자가 없습니다" 오류를 발생시키고 있습니다.여기 그것을 위한 해결책이 있다(더러운 느낌이 들지만, 나는 더 나은 것을 만들 기술이 부족하다).
된 각 합니다.roleGuard
.
따라서 선택한 모든 역할에 대해:
canActivate: [roleGuard('foo')]
다음 조건을 충족해야 합니다.
providers: [roleGuard('foo')]
@@AluanHaddad의 됩니다.roleGuard
, 「 「」의 roles
파라미터가 동일합니다.「」를 사용합니다.lodash.memoize
음음음같 뭇매하다
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;
}
}
});
각 역할 조합은 새 클래스를 생성하므로 역할 조합마다 공급자로 등록해야 합니다.즉, 다음과 같은 경우:
canActivate: [roleGuard('foo')]
★★★★★★★★★★★★★★★★★」canActivate: [roleGuard('foo', 'bar')]
다 요.providers[roleGuard('foo'), roleGuard('foo', 'bar')]
를 'Da'의 입니다.roleGuard
하지만 말했듯이, 저는 그것을 구현할 기술이 부족합니다.
은 른른른 、 R 、 R 、 R 、 R 、 R 、 R 。InjectionToken
을 사용법
export class AccessGuard {
static canActivateWithRoles(roles: string[]) {
return new InjectionToken<CanActivate>('AccessGuardWithRoles', {
providedIn: 'root',
factory: () => {
const authorizationService = inject(AuthorizationService);
return {
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): <boolean | UrlTree > | Promise<boolean | UrlTree> | boolean | UrlTree {
return authorizationService.hasRole(roles);
}
};
},
});
}
}
그리고 이렇게 사용하세요.
canActivate: [AccessGuard.canActivateWithRoles(['ADMIN'])]
해서 하는 이 있어요.useFactory
★★★★★★★★★★★★★★★★★」providers
:
const routes: Routes = [
{
path: 'super-user-stuff',
component: SuperUserStuffComponent,
// Name can be whatever you want
canActivate: ['CanActiveSuperUserStuffGuard']
}
]
★★★★★★★★★★★★★★★.providers
하다
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
providers: [
{
provide: 'CanActiveSuperUserStuffGuard',
useFactory: () => new RoleGuard('superUser')
}
]
})
export class YourRoutingModule {
}
.providedIn: 'root'
나가주세요)@Injectable()
과 같이 합니다.
constructor(@Inject('roleName') private readonly roleName: string) {
}
주의하세요!!!이 방법을 사용하면 모든 선언에 대해 새로운 가드인스턴스가 생성됩니다.
언급URL : https://stackoverflow.com/questions/42719445/pass-parameter-into-route-guard
'itsource' 카테고리의 다른 글
스트라이프 오류: '토큰이 지원되지 않습니다' 구독에 등록하려고 하면 (0) | 2023.04.02 |
---|---|
Postgresql vs Oracle (0) | 2023.04.02 |
스크립트에서 인라인 HTML에 반응하지 않고 jsx를 사용할 수 있습니까? (0) | 2023.04.02 |
노드를 사용하여 DynamoDB의 JSON 어레이에 새 개체 추가JS (0) | 2023.04.02 |
리액트 렌더 함수에서 동적 href를 생성하는 방법 (0) | 2023.04.02 |