试图了解CanActivate和CanActivateChild之间的差异

时间:2017-03-06 17:41:21

标签: angular angular2-guards

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

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
  }

}

当我尝试访问' / admin'和' / admin / edit'只有canActivate(评论为canActivateChild)控制台显示

Guarding...

当我删除canActivate并将canActivateChild带回控制台显示

Guarding children...

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

PS:我认为canActivateChild在激活子路由之前运行。但那有什么好处呢?难道只保留其中一个吗?

3 个答案:

答案 0 :(得分:18)

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

示例:您可能遇到必须对用户进行身份验证才能导航到根组件的情况,但必须具有权限“x”才能访问子组件。在这种情况下,canActivateChild可以节省大量的输入,因为必须为每个孩子添加canActivate警卫。

编辑:

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

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

这需要从上到下受到保护。未经授权访问任何路由,包括root和children。在这种情况下,根级canActivate可以很好地保护所有内容。

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

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

在这种情况下,也许所有用户都需要访问根组件的featureA'和'featureB',但只有某些用户需要能够导航到'featureA'的子路由。在这种情况下,更容易在根级别使用一个防护装置来保护儿童,而不是根本身。另一种方法是在每条儿童路线上放置canActivate警卫,这可能会很乏味。

这完全取决于您的要求,但同时选择canActivatecanActivateChild可能会很好。

答案 1 :(得分:0)

在我看来,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方法,但这不是重点。

答案 2 :(得分:0)

<头>
sr 号 可以激活 CanActivateChild
1 它阻止访问父路由,其中​​还包括访问所有子路由 我们可以访问父路由,但如果需要,我们可以选择使用 canActivateChild 来阻止特定的子路由
2 是的,您可以通过将 CanActivate 应用于所有子路由来实现 CanActivateChild 行为 只在父路由添加CanActivateChild,可以节省大量时间,也更方便

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


说明 CanActivate 和 CanActivateChild 区别的路径
canactivatedchild vs canactive example

CanActivate:计算机系学生不能访问其他系
CanActivateChild:计算机系学生可以访问计算机系(在本例中为父系),但不能访问计算机系的一个子系,即教师角色访问权限