在Angular 2应用程序中为所有路径使用基准防护

时间:2016-11-10 09:03:17

标签: angular angular2-routing angular2-guards

有没有办法设置"基地"在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吗?我想配置一个" base" canActivate适用于此应用程序中的所有路由。

2 个答案:

答案 0 :(得分:7)

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

答案 1 :(得分:5)

我已经编写了一个解决方案,可以为我的应用的每个路径(包括子模块定义的路径)动态添加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];
  }
}