2

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.

Jaidev Khatri
  • 159
  • 4
  • 15
  • Pleas provide a working stackblitz.com with at least part of the code so we can provide you some help. – akpgp Nov 20 '19 at 07:26
  • You could use another guard. Here‘s an example, how they solved a similar problem: https://stackoverflow.com/q/40589878 – insertusernamehere Nov 20 '19 at 07:35
  • @insertusernamehere I thought the similar idea, but how will Roleguard know which component or route is accessed to filter out from the list of arrays. note I am new to angular. – Jaidev Khatri Nov 20 '19 at 07:52

3 Answers3

4

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.

Tom Slabbaert
  • 21,288
  • 10
  • 30
  • 43
  • this is already been implemented, it is something like I don't have any Role but list of components or routes a user can access. – Jaidev Khatri Nov 20 '19 at 07:49
  • i edited my answer to match your needs however i less recommend doing it this way as its a lot of work to maintain – Tom Slabbaert Nov 20 '19 at 08:12
1

I suggest that you use ngx-permissions, check this. it works perfectly to give access based on roles in your template or routes, you can load your permissions for each user just after authentication

this.permissionsService.loadPermissions(perm);

and then there you can use them everywhere canActivate, canLoad to manage access

 const appRoutes: Routes = [
 {
  path: 'lazy',
   data: {
    permissions: {
     except: 'ADDDMIN',
    }
  },
  canLoad: [NgxPermissionsGuard],
  loadChildren: 'app/lazy-module/lazy-module.module#LazyModule'
},
];

@NgModule({
 imports: [
  RouterModule.forRoot(appRoutes)
 ],
 exports: [
   RouterModule
 ],
 providers: [
  // CanDeactivateGuard
 ]
})
export class AppRoutingModule {}
Fateh Mohamed
  • 20,445
  • 5
  • 43
  • 52
0

you need to create different-different Module according to role based authorization on user and each Molude have one base routing file is there you need to check this module authorized according to user or not with use AuthGuard in routing.