web-dev-qa-db-ja.com

Angular 2アプリケーションのすべてのルートにベースガードを使用する

Angular2でルートを設定するときに「ベース」canActivateを設定する方法はありますか?すべてのルートが同じベースチェックでカバーされるように、各ルートはより詳細なチェックを持つことができます。

私は次のようなルーティングを持つAppModuleを持っています:

@NgModule({
    imports: [
        RouterModule.forRoot([
            {
                path: '',
                component: HomeComponent,
                canActivate: [AuthenticationGuardService],
                data: { roles: [Roles.User] }
            }
        ])
    ],
    exports: [
        RouterModule
    ]
})
export class AppRoutingModule { }

そして、機能モジュールの場合FeatureModule

@NgModule({
    imports: [
        RouterModule.forChild([
            {
                path: "feature",
                component: FeatureComponent,

                // I'd like to avoid having to do this:
                canActivate: [AuthenticationGuardService],
                data: { roles: [Roles.User] }
            }
        ])
    ],
    exports: [
        RouterModule
    ]
})
export class FeatureRoutingModule { }

AuthenticationGuardServiceで提供されている役割を使用して、ユーザーがルートにアクセスできるかどうかをdataに確認させます。

すべての機能ルーティングモジュールでcanActivatedataを設定する必要がないように何かすることはできますか?このアプリケーションのすべてのルートに「ベース」canActivateを設定したいだけです。

14
Joel
const routes: Routes = [
  {
    path: '',
    canActivate: [AuthGuard],
    children: [
      { path: '', component: HomeComponent },
      { path: 'builds', component: BuildsComponent },
      { path: 'files', component: FilesComponent },
      { path: 'publications', component: PublicationsComponent }
    ]
  },
  { path: 'login', component: LoginComponent },
  { path: '**', redirectTo: '' }
];
8

アプリのすべてのルート(子モジュールで定義されたルートを含む)にGuardを動的に追加するソリューションを作成しました。

this Router Docs を読みながら、この解決策を見つけました。

編集

これが生きている StackBlitz サンプルです。

const routes: Routes = [
  { path: '', redirectTo: 'home', pathMatch: 'full' },
  { path: 'login', component: LoginComponent, data: { skipGuard: true } },
  { path: '403', component: ForbiddenComponent, data: { skipGuard: true } },
  { path: '**', component: NotFoundComponent, data: { skipGuard: true } }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
  providers: []
})
export class AppRoutingModule {
  
  constructor(router: Router) {
    router.config
        .filter(route => !route.data || !route.data.skipGuard)
        .forEach(route => this.addGuard(route));
  }
  
  private addGuard(route: Route): void {
    route.canActivate = route.canActivate ? 
                   [AuthGuard].concat(route.canActivate) : [AuthGuard];
    route.canActivateChild = route.canActivate ? 
                   [AuthGuard].concat(route.canActivate) : [AuthGuard];
  }
}
7
Jorge Ciombalo