In this exaple project with JWT authentication we se how to allow only authenticated users to some route:
import { RouterConfig } from '@angular/router'; import { Home } from './home'; import { Login } from './login'; import { Signup } from './signup'; import { AuthGuard } from './common/auth.guard'; export const routes: RouterConfig = [ { path: '', component: Login }, { path: 'login', component: Login }, { path: 'signup', component: Signup }, { path: 'home', component: Home, canActivate: [AuthGuard] }, { path: '**', component: Login }, ];
I would like make step further and also indicate what user role have 'access' to route - but I don't know how to pass argument to canActivate AuthGuard (src). So I would like to achieve something like this (for instance I have two roles: Admin and Employee):
{ path: 'home', component: Home, canActivate: [AuthGuard] }, { path: 'users', component: AdminUsers, canActivate: [AuthGuard('Admin')] }, { path: 'users', component: Employees, canActivate: [AuthGuard('Employee')] },
Where my AuthGuard could look something like this (where userRole(= Admin or Employee or null) is passed parameter to AuthGuard):
@Injectable() export class AuthGuard implements CanActivate { constructor(private router: Router) {} canActivate(userRole) { if (!userRole || JWT.user().role == userRole) { return true; } this.router.navigate(['/login']); return false; } }
where JWT.user.role is helper which read user role stored in JWT token. Is there a way to do something similar like above idea?
The differences If we directly navigate to the child route, the canActivate guard will also be executed. canActivateChild will always be executed while navigating to/between child routes. For example, if we're at a child route child/1 and we navigate to child/2 , the guard will get executed.
CanActivatelinkInterface that a class can implement to be a guard deciding if a route can be activated. If all guards return true , navigation continues. If any guard returns false , navigation is cancelled.
Include AuthGuard to Route Now for each request of the route, the verify() function will be called and if the verify() function returns true, then only we can access the particular route. If it returns false, we are not able to access it. This is how we can restrict the routes from unauthorized user access.
AuthGuard is used to protect the routes from unauthorized access. So here we are creating an AuthGuard in angular that will protect our routes from unauthorized access. Example: We can create an AuthGuard by running simple command using CLI. ng g guard services/auth.
You can set the data
parameter of the route with the role like this
const appRoutes: Routes = [ { path: 'account/super-secure', component: SuperSecureComponent, canActivate: [RoleGuard], data: { roles: ['super-admin', 'admin'] } }];
and then have this in canActivate
of RoleGuard
:
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { let roles = route.data["roles"] as Array<string>; return (roles == null || roles.indexOf("the-logged-user-role") != -1); }
I think this could be another way of doing it instead of creating guard for every role. I would actually take this rout since it requires less code and handles the problem very nicely.
The signature for CanActivate
won't allow you to pass a userRole
like you want to. https://github.com/angular/angular/blob/2.0.0-rc.4/modules/%40angular/router/src/interfaces.ts#L54
It's probably best to do separate classes for each of your user role cases. That's the guidance in the official docs too: https://angular.io/docs/ts/latest/api/router/index/CanActivate-interface.html
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