Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trying to understand the differences between CanActivate and CanActivateChild

So, I'm trying to protect the access to several routes by using guards. I'm using the following routes to do so :

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

Here's a look at what AuthGuardService looks like

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
  }

}

When I try to access to '/admin' and '/admin/edit' with canActivate only (canActivateChild is commented) the console displays

Guarding...

When I remove canActivateand bring canActivateChildback the console displays

Guarding children...

When I keep both, it goes back to displaying Guarding.... So, my question is what's the purpose of having canActivateChild when canActivateprotects both the root element and the children ?

PS : I get it that canActivateChild runs before the child route is activated. But what are the benefits of that ? Isn't keeping only one of them sufficient ?

like image 435
YounesM Avatar asked Mar 06 '17 17:03

YounesM


1 Answers

In my view, the CanActivate is used to restrict access from a certain path and all the sub-paths and CanActivateChild is used to restrict access to a specific group inside the CanActivate path.

Example:

{
  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: ...
        }
      ]
    }
  ]
}

Because you need two types of validations, you cannot have two canActivate methods, so you need the canActivateChild for checking the permision inside the canActivate path. Obviously, you can create a different guard service (AuthGuardForChildrenRoutes) and still use canActivate method, but that's not the point.

like image 181
Marius Lazar Avatar answered Sep 29 '22 12:09

Marius Lazar