Использование базовой защиты для всех маршрутов в приложении Angular 2

Есть ли способ установить "base" canActivate при настройке маршрутов в Angular2? Чтобы все маршруты были покрыты одной и той же базовой проверкой, а затем каждый маршрут может иметь более детальную проверку.

У меня есть 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.

Могу ли я сделать что-то, чтобы избежать установки canActivate и data во всех модулях маршрутизации функций? Я хотел бы просто настроить "base" canActivate для всех маршрутов в этом приложении.

Ответ 1

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: '' }
];

Ответ 2

Я написал решение для динамического добавления Guard для каждого маршрута моего приложения (включая маршруты, определенные дочерними модулями).

Я разобрался с этим решением при чтении этой документации по маршрутизатору.

редактировать

Вот живой образец 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];
  }
}