Role based system in Angular

163 views Asked by At

I would like to ask, how I can create the role based system in Angular. In my application, I have created the class app-routing.ts, where i would like to define

  • ClientComponent can open only the authorizated user with role client
  • AssistantsComponent can open only the authorizated user with role admin
const routes: Routes = [
  { path: '', component: AuthComponent},
  { path: 'assitants', component: AssitantsComponent , canActivate: [AuthGard]},
  { path: 'client', component: ClientComponent, canActivate: [AuthGard]}
]

The authorization is solved in AuthGard.ts:

export class AuthGard implements CanActivate{

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | UrlTree | Observable<boolean | UrlTree> | Promise<boolean | UrlTree> {
  
     const accessToken = localStorage.getItem(AuthGard.LOCAL_STORAGE_ACCESS_TOKEN)
     if(!!accessToken){
         return true
     }else{
         return this.router.createUrlTree(['/auth'])
     }
  }
    
}

Question: Is it possible to use some general method, how i can solved this role access?

thank you very much

1

There are 1 answers

1
Jacopo Sciampi On BEST ANSWER

I've done it as following - assuming that the role of the user is stored in the JWT.

I defined an enum with all the roles:

export enum ROLE_LIST_ENUM {
   "ADMIN" = "ADMIN",
   "CLIENT" = "CLIENT"
}

Then, I added the role(s) needed to each route to be activated :

const routes: Routes = [
  { path: '', component: AuthComponent},
  { path: 'assitants', 
    component: AssitantsComponent,
    canActivate: [AuthGard],
    data: { roles: [ROLE_LIST_ENUM.ADMIN]} 
  },
  { path: 'client',
    component: ClientComponent,
    canActivate: [AuthGard]
    data: { roles: [ROLE_LIST_ENUM.CLIENT]}
  }
]

Finally, in the AuthGuard:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | UrlTree | Observable<boolean | UrlTree> | Promise<boolean | UrlTree> {
  
     const accessToken = localStorage.getItem(AuthGard.LOCAL_STORAGE_ACCESS_TOKEN)
     if(!accessToken){
         return this.router.createUrlTree(['/auth'])
     }

     return this._hasRole(route.data);
  }

private _hasRole(data: GENERIC_KEY_VALUE_INTERFACE): boolean {
        const userAvailableRoleList = jwtDecode<yourInterface>(yourToken).roles;
        const hasRole = !!(data['roles'] as string[])?.find(e => userAvailableRoleList.find(list => list === e));

        return hasRole;
    }

export interface GENERIC_KEY_VALUE_INTERFACE {
  [key: string]: any;
}

Basically route.data holds the roles array defined in the routing file. The JWT token store some information - the user's role too. So I used jwtDecode to decode the token and get the roles of the user. Then I checked if the user has the correct role in its list, to be able to navigate to the given route.