だから、私は警備員を使っていくつかのルートへのアクセスを保護しようとしています。私はそうするために次のルートを使用しています:
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
のみ(canActivateChild
がコメント化されている)で「/ admin」および「/ admin/edit」にアクセスしようとすると、コンソールに表示されます
Guarding...
canActivate
を削除してcanActivateChild
を戻すと、コンソールに表示されます
Guarding children...
両方を保持すると、Guarding...
の表示に戻ります。だから、私の質問は、canActivateChild
がルート要素と子の両方を保護するときにcanActivate
を持つ目的は何ですか?
PS:子ルートがアクティブになる前にcanActivateChild
が実行されることがわかりました。しかし、その利点は何ですか?そのうちの1つだけで十分ではありませんか?
ユーザーがルートコンポーネントにアクセスできる要件が異なる場合がありますが、子コンポーネントの条件を満たしていない可能性があるため、両方が重要です。
例:ルートコンポーネントに移動するにはユーザーを認証する必要があるが、子コンポーネントに移動するには権限「x」が必要な状況が発生する可能性があります。このような場合、canActivateChild
を使用すると、各子にcanActivate
ガードを追加する必要がなくなります。
編集:
たとえば、すべてのルートを不正な侵入から保護する必要がある管理モジュールがあるとします。
{
path: 'admin',
component: AdminComponent,
canActivate: [ AuthGuardService ],
children : [
{
path: '', component: ...,
},
{
path: 'manage-users', component: ...,
},
{
path: 'manage-roles', component: ...,
}
]
}
これはトップダウンから保護する必要があります。ルートと子を含むルートへの不正アクセスはありません。この状況では、ルートレベルのcanActivate
はすべてを保護するのに最適です。
ただし、特定の子のみを保護する必要がある機能モジュールがある場合もあります。
{
path: 'featureA',
component: ...,
canActivateChild: [ AuthGuardService ],
children : [
{
path: 'manage-feature', component: ...,
},
{
path: 'manage-members', component: ...,
}
],
{path: 'featureB', component: ...}
}
この状況では、すべてのユーザーがルートコンポーネント「featureA」および「featureB」にアクセスする必要があるかもしれませんが、特定のユーザーのみが「featureA」の子ルートに移動できる必要があります。この場合、ルートレベルで1つのガードを使用して子を保護する方が簡単ですが、ルート自体は使用しません。別の方法は、各子ルートに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: ...
}
]
}
]
}
2種類の検証が必要なため、2つのcanActivate
メソッドを持つことはできません。したがって、canActivateChild
パス内の権限をチェックするためにcanActivate
が必要です。明らかに、別のガードサービス(AuthGuardForChildrenRoutes
)を作成し、それでもcanActivate
メソッドを使用できますが、それは重要ではありません。
あなたの例では、canActivateChild内でcanActivateを呼び出したため、子ルート間を移動するときに両方のガードが呼び出されます。両方のガード内に異なる認証ロジックがある場合、子ルート間を移動している間、canActivateガードは実行されません。