12

所以,我试图通过使用警卫来保护对多条路线的访问。我正在使用以下路线这样做:

const adminRoutes : Routes = [
  {
    path: 'admin',
    component: AdminComponent,
    canActivate: [ AuthGuardService ],
    children : [
      {
        path: '',
        canActivateChild: [ AuthGuardService ],
        children: [
          { path: 'edit', component: DashboardComponent},
          { path: '', component: DashboardComponent}
        ]
      }
    ]
  }
];

看看是什么AuthGuardService样子的

import { Injectable } from '@angular/core';
import {CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot} from "@angular/router";

@Injectable()
export class AuthGuardService implements CanActivate{

  constructor(private router: Router) { }

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot){
    console.log("Guarding...");
    return this.sessionValid();
  }

  canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot){
    console.log("Guarding children...");
    return this.canActivate(route, state);
  }

  sessionValid() : boolean {
    //tests
  }

}

canActivate当我尝试仅使用(已注释)访问“/admin”和“/admin/edit”时canActivateChild,控制台显示

Guarding...

当我移除canActivatecanActivateChild带回控制台显示

Guarding children...

当我保留两者时,它会回到显示Guarding...。所以,我的问题是什么canActivateChild时候canActivate保护根元素和子元素的目的是什么?

PS:我得到它canActivateChild在子路由激活之前运行。但是这样做有什么好处呢?只保留其中一个还不够吗?

4

4 回答 4

24

两者都很重要,因为您可能有不同的要求,用户可以访问根组件,但可能不满足子组件的条件。

示例:您可能遇到这样一种情况,用户必须经过身份验证才能导航到根组件,但必须具有权限“x”才能访问子组件。在这种情况下,不必为每个孩子canActivateChild添加警卫,从而节省了大量的打字时间。canActivate

编辑:

例如,您可能有一个管理模块,其中所有路由都需要防止未经授权的进入:

  {
    path: 'admin',
    component: AdminComponent,
    canActivate: [ AuthGuardService ],
    children : [
      {
        path: '', component: ...,
      },
      {
        path: 'manage-users', component: ...,
      },
      {
        path: 'manage-roles', component: ...,
      }
    ]
  }

这需要自上而下加以保护。没有未经授权的访问任何路由,包括根和子。在这种情况下canActivate,根级别可以很好地保护一切。

但是您也可能有一个功能模块,其中只需要保护某些孩子:

  {
    path: 'featureA',
    component: ...,
    canActivateChild: [ AuthGuardService ],
    children : [
      {
        path: 'manage-feature', component: ...,
      },
      {
        path: 'manage-members', component: ...,
      }
    ],
    {path: 'featureB', component: ...}
  }

在这种情况下,可能所有用户都需要到达根组件“featureA”和“featureB”,但只有某些用户需要能够导航到“featureA”的子路由。在这种情况下,更容易在根级别使用一个保护来保护孩子,而不是根本身。另一种方法是canActivate在每个子路径上设置警卫,这可能会变得乏味。

这实际上完全取决于您的要求,但是同时具有 和 选项可能会canActivate很好canActivateChild

于 2017-03-06T17:53:47.210 回答
2

在我看来,CanActivate用于限制来自某个路径和所有子路径CanActivateChild的访问,用于限制对路径内特定组的访问CanActivate

例子:

{
  path: 'admin',
  component: AdminComponent,
  canActivate: [AuthGuardService],
  children : [
    {
      path: 'books', component: ...,
    },
    {
      path: 'authors', component: ...,
    },
    {
      path: 'payments',
      canActivateChild: [AuthGuardService],
      children: [
        {
          path: 'list', component: ...
        },
        {
          path: 'list/:id', component: ...
        }
      ]
    }
  ]
}

因为你需要两种类型的验证,你不能有两种canActivate方法,所以你需要canActivateChild检查canActivate路径内的权限。显然,您可以创建一个不同的保护服务 ( AuthGuardForChildrenRoutes) 并仍然使用canActivate方法,但这不是重点。

于 2017-10-13T12:01:38.417 回答
1
sr没有。 可以激活 可以激活孩子
1 它阻止对父路由的访问,其中还包括对所有子路由的访问 我们可以访问父路由,但如果需要,我们可以选择使用 canActivateChild 阻止特定的子路由
2 是的,您可以通过将 CanActivate 应用于所有子路由来实现 CanActivateChild 行为 只需在父路由添加 CanActivateChild 即可节省大量时间,更方便

现在这是 canActivate 和 canActivatedchild 之间的基本区别,
这是可以使用这两者的情况


说明 CanActivate 和 CanActivateChild 之间区别的路径 CanActivate:计算机系学生无法访问其他部门 CanActivateChild:计算机系学生可以访问计算机系(在这种情况下是父系)但不能访问计算机系的一个孩子,即教师角色使用权
canactivatedchild 与 canactive 示例


于 2021-05-12T09:21:10.353 回答
0

在您的示例中,您在 canActivateChild 中调用了 canActivate,因此当您在子路由之间遍历时,两个警卫都会被调用。如果你在两个守卫内部有不同的身份验证逻辑,你的 canActivate 守卫在子路由之间遍历时不会执行。

于 2019-03-10T15:37:59.680 回答