ChatGPT解决这个技术问题 Extra ChatGPT

具有无组件路由的 CanActivate 与 CanActivateChild

关于 Route Guards 的 angular2 文档让我不清楚何时将 CanActivate 防护与 CanActivateChild 防护与无组件路由结合使用是合适的。

TL;DR:当我可以使用带有 canActivate 的无组件路由来实现相同效果时,拥有 canActivateChild 有什么意义?

长版:

我们可以在路由层次结构的每一层都有多个警卫。路由器首先检查 CanDeactivate 和 CanActivateChild 守卫,从最深的子路由到顶部。然后它从上到下检查 CanActivate 守卫到最深的子路由。

我知道 CanActivateChild 是自下而上检查的,而 CanActivate 是自上而下检查的。对我来说没有意义的是文档中给出的以下示例:

@NgModule({    
  imports: [
    RouterModule.forChild([
      {
        path: 'admin',
        component: AdminComponent,
        canActivate: [AuthGuard],
        children: [
          {
            path: '',
            canActivateChild: [AuthGuard],
            children: [
              { path: 'crises', component: ManageCrisesComponent },
              { path: 'heroes', component: ManageHeroesComponent },
              { path: '', component: AdminDashboardComponent }
            ]
          }
        ]
      }
    ])
  ],
  exports: [
    RouterModule
  ]
})
export class AdminRoutingModule {}

所以 admin 路径有一个无组件路由:

查看 AdminComponent 下的子路由,我们有一个带有路径和子属性的路由,但它没有使用组件。我们的配置没有出错,因为我们可以使用无组件路由。

为什么这种情况下的代码在子组件和根组件(路径 admin)中插入 AuthGuard?从根本上守卫还不够吗?

我根据删除 canActivateChild: [AuthGuard] 并在 AdminDashboard 上添加注销按钮的示例创建了一个 plunkr。果然,父路由的 canActivate 仍然守卫,那么当我可以使用带有 canActivate 的无组件路由时,拥有 canActivateChild 有什么意义呢?

我想知道同样的事情,你有没有机会在 github 上发布这个?
这是同一个问题,也许对你有帮助:stackoverflow.com/questions/42632154/…
我认为您仍然可以在根 admin 路径上有一个 canActivateChild,这样您就不需要无组件路由。我相信这里的无组件方法在指南中被用来证明我们甚至可以更进一步,对相关的子路由进行分组,以便对它们应用更专业的防护。

M
Matej

From the docs:

正如我们了解使用 CanActivate 保护路由一样,我们还可以使用 CanActivateChild 保护来保护子路由。 CanActivateChild 守卫与 CanActivate 守卫类似,但不同之处在于它在每个子路由被激活之前运行。我们保护我们的管理功能模块免受未经授权的访问,但我们也可以保护我们的功能模块中的子路由。

这是一个实际的例子:

导航到 /admin canActivate 已选中 您在 /admin 路由的子级之间导航,但不会调用 canActivate ,因为它保护 /admin canActivateChild 在其定义的路由的子级之间发生更改时被调用。

我希望这对您有所帮助,如果仍然不清楚,您可以通过添加调试它们的守卫来检查特定功能。


但为什么不直接将 AuthGuard 作为 CanActivateChild 放在 AdminComponent 上。我不明白添加额外的无组件路由有什么好处?
我想它会在以后的框架中以某种方式改变。总是有更简单的解决方案。
P
Peter Li

在现实世界中,我觉得为父母及其所有孩子使用同一个警卫是多余的。

举个更好的例子,假设您有管理员用户的角色(编辑/查看),您可以为“编辑”标签添加保护。

    RouterModule.forChild([
      {
        path: 'admin',
        component: AdminComponent,
        canActivate: [AuthGuard],  //1 - redirect to login page if not logged in
        children: [
          //View Access
          {
            ......
          },
          //Edit Access
          {
            path: '',
            canActivateChild: [EditGuard], //2 - display "you don't have Edit permission to access this page"
            children: [
              { path: 'crises', component: ManageCrisesComponent },
              { path: 'heroes', component: ManageHeroesComponent },
              { path: '', component: AdminDashboardComponent }
            ]
          }
        ]
      }
    ])

我不认为这是多余的。我认为第一个页面加载,会调用 canActivate 和 canActivate child,但是当从一个孩子导航到另一个孩子时,不会调用 canActivate 而是调用 canActivateChild,例如检查 JWT 是否仍然有效或需要静默刷新,只是我的预感。
c
crystalw

我还混淆了 angular2 关于 routeGuard 的文档。 CanActivate 防护和 CanActivateChild 防护有什么区别。

我有一些发现,希望对你有所帮助。

auth-guard.service.ts 文件中

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
let url: string = state.url;

return this.checkLogin(url);
}

canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
return this.canActivate(route, state);
}

因为在 canActivateChild 函数中调用了 canActivate 方法。您可以编写一段不调用 canActivateChild 函数中的 canActivate 方法的代码片段。


A
Alejandro Gianetti

我能想到的一个原因是超时。

我开始使用 Angular 2,使用身份验证提供程序。此提供程序使已空闲超过一定时间的会话到期。

在您让计算机保持登录状态并且会话过期的常见情况下,您尝试的下一次导航必须验证您当前的情况。如果您在子路由之间导航,我认为 CanActivateChild 是检测过期会话并触发重定向登录的守卫,而 CanActivate 根本不会触发。

免责声明:这来自我的头脑,我还没有实现它。


S
Simon_Weaver

如果您定义了 10 个孩子怎么办。

如果他们都有共同的要求,那么 canActivateChild 只需要去一个地方,而不是每个孩子 10 个canActivate


您仍然可以在无组件路由上使用一个 canActivate
R
Ravid Goldenberg

TL;DR: CanActivateCanActivateChild 不适用于无组件路由。

我相信文档只是忽略了无组件路线中两个守卫的必要性,因为其目的只是为了在文档的特定里程碑中展示无组件路线以及在另一个中使用两个守卫。

在特定场景中使用这两种保护非常有用,例如:允许登录查看多个组件的管理仪表板,如邮件、日志统计、资源使用等 - 在此级别,访问受到 CanActivate 保护的限制- 当试图导航到每个组件时,每个管理员用户的角色由 CanActivateChild 守卫检查。