在Angular 2应用程序中对所有路线使用基础防护装置

在Angular 2应用程序中对所有路线使用基础防护装置,angular,angular2-routing,angular2-guards,Angular,Angular2 Routing,Angular2 Guards,在Angular2中配置路由时,是否有方法设置“基本”canActivate?因此,所有路由都被相同的基本检查覆盖,然后每个路由都可以进行更精细的检查 我有一个AppModule,路由如下: @NgModule({ imports: [ RouterModule.forRoot([ { path: '', component: HomeComponent,

在Angular2中配置路由时,是否有方法设置“基本”
canActivate
?因此,所有路由都被相同的基本检查覆盖,然后每个路由都可以进行更精细的检查

我有一个
AppModule
,路由如下:

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

@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
?我只想为此应用程序中的所有路由配置一个“基本”
canActivate

我已经编写了一个解决方案,为我的应用程序的每个路由(包括子模块定义的路由)动态添加防护

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: '' }
];
我在阅读时想出了这个解决办法

编辑

这是一个活的样本

const routes:routes=[
{路径:'',重定向到:'home',路径匹配:'full'},
{path:'login',组件:LoginComponent,数据:{skipGuard:true},
{路径:'403',组件:禁止组件,数据:{skipGuard:true},
{路径:'**',组件:NotFoundComponent,数据:{skipGuard:true}
];
@NGD模块({
导入:[RouterModule.forRoot(路由)],
导出:[路由模块],
提供者:[]
})
导出类批准模块{
构造器(路由器:路由器){
router.config
.filter(route=>!route.data | |!route.data.skipGuard)
.forEach(route=>this.addGuard(route));
}
专用addGuard(路由:路由):无效{
route.canActivate=route.canActivate?
[AuthGuard].concat(route.canActivate):[AuthGuard];
route.canActivateChild=route.canActivate?
[AuthGuard].concat(route.canActivate):[AuthGuard];
}

}
您可以从类或助手函数创建路由对象。这是最简单的(可能也是唯一可用的)解决方案。@estus你的意思是我应该这样做:
RouterModule.forChild([helperService.getRoute(“feature”,FeatureComponent)])
?然后那个助手服务(或类或方法…)总是将基本保护添加到生成的路由对象中?是的。我个人会使用类似于
RouterModule.forChild([newauthenticatedRoute({path:…,component:…})])的东西。
@Joel,裁决是什么?你介意分享你的AuthenticationGuardService吗?在进一步的谷歌搜索中,这听起来像是一个解决方案@sawe还没有找到我满意的解决方案。你链接到的那个是可以的,但是仍然需要你把它放在所有的路由模块中,这目前是不安全的,因为通过
forChild
添加的子路由作为同级添加到
forRoot
路由,因此不在层次结构中,不会触发防护。要使其正常工作,您应该使用
canActivateChild
而不是
canActivate
。请快速注意,如果对于非跳过的路由,
route.canActivate
未定义,则更新的
route.canActivate
将使用上述答案生成
[AuthGuard,未定义]
。这实际上很难调试,也很难找到导致错误的真正原因。我试图实现这一点,但我做不到。增加了防护,但每次导航都会出错。可能是因为我的guard在
AppRoutingModule
中注入时具有不同的依赖关系。你有关于stackblitz之类的例子吗?谢谢。@MarcosDimitrio我刚刚编辑了答案,加入了StackBlitz演示。@ar27111994我已经修复了您指出的错误。在我包含的stackblitz链接中查看。