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:
Both are important because you may have differing requirements where a user can get to the root component, but may not meet conditions for child components.
Example: You could have a situation where a user must be authenticated to navigate to the root component, but must have permission 'x' to get to child components. In cases like this, canActivateChild
saves a lot of typing from having to add canActivate
guards to each of the children.
EDIT:
For example, you may have an Admin Module where all routes need to be guarded against unauthorized entry:
{
path: 'admin',
component: AdminComponent,
canActivate: [ AuthGuardService ],
children : [
{
path: '', component: ...,
},
{
path: 'manage-users', component: ...,
},
{
path: 'manage-roles', component: ...,
}
]
}
This would need to be protected from the top down. No unauthorized access to any of the routes, including the root and children. In this situation canActivate
at the root level works great to protect everything.
But you may also have times where you have a Feature module where only certain children need to be guarded:
{
path: 'featureA',
component: ...,
canActivateChild: [ AuthGuardService ],
children : [
{
path: 'manage-feature', component: ...,
},
{
path: 'manage-members', component: ...,
}
],
{path: 'featureB', component: ...}
}
In this situation, maybe all users need to get to the root components 'featureA' and 'featureB', but only certain users need to be able to navigate to the child routes of 'featureA'. In this case it is easier to use one guard at the root level to protect the children, but not the root itself. The alternative is to put canActivate
guards on each child route, which could get tedious.
It really all depends upon your requirements, but it can be nice to have both options of canActivate
and canActivateChild
.
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.
In your example you have called canActivate inside canActivateChild, hence both the guards are getting called when you are traversing among child routes. If you were to have different authentication logic inside both the guards, your canActivate guard won't execute while traversing among child routes.