Search code examples
angularpermissionsroutesauthorization

Access Routes based on user dynamic permissions in Angular 6 or later


I have applied role-based authorization on the user who is logged in. The JWT token is getting stored in localStorage and routes getting access based on Login and auth.guard.ts.

But in addition to this certain users need to access some components that others with the same role don't. A JSON array is defining which routes users can access even after login.

What I have defined to get this done is to check on the ngOnInit of the component. If the component is present in the array, it should be allowed to access other 404 page has to be displayed.

But seems like I am not finding this way as an effective way to do so.

Please suggest any improvisation I can do with illustration. Would like to do everything to be done in the right way.


Solution

  • You can Role validation to a specific route:

    const routes: Routes = [
        {   //todo route you want to add validation for
            path: 'route',
            component: Component,
            canActivate: [AuthGuard],
            data: { roles: ["Admin"] } //recommend you dont use string here.
        },
        { path: '**', redirectTo: '' }
    ];
    

    And then just add these lines to your existing canActivate funciton:

        let currentUser = User;
        if (route.data.roles && route.data.roles.indexOf(currentUser.role) === -1) {
            // role not authorised so redirect to home page
            this.router.navigate(['/']);
            return false;
        }
    

    Read the docs here.

    EDIT:

    I recommend you use role routes as its easier to maintain and more consisted however you can just add something like this to your canActivate function:

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
         let stateName: string = state.url.replace("/", "");
         let currentUser = User;
         if (currentUser.routePermissions.includes(stateName)) {
             // route not authorised so redirect to home page
             this.router.navigate(['/']);
             return false;
         }
    }
    

    Instead of an array maybe use a route object like and just match on actual false match.

    user.routePermissions = {
        'route1': false
    }
    

    this will make it easier to maintain as you won't need to update all your users for a new route added.