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 clientAssistantsComponent
can open only the authorizated user with role adminconst 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
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.