Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2 routing canActivate and AuthGuard (JWT) with user role parameter

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?

like image 896
Kamil Kiełczewski Avatar asked Jul 15 '16 18:07

Kamil Kiełczewski


People also ask

What is the difference between CanActivate and CanActivateChild?

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.

What is CanActivate in Angular routing?

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.

How would I restrict access to routes in Angular?

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.

What is AuthGuard angular10?

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.


2 Answers

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.

like image 120
Arman Avatar answered Sep 19 '22 12:09

Arman


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

like image 26
cienki Avatar answered Sep 19 '22 12:09

cienki