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 canActivate
and bring canActivateChild
back 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 canActivate
protects 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 ?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With