As mentioned by Rahul in the comment, using Guard
is an out-of-the-box solution that may meet your requirements.
It's important to note that guards are specifically for routing purposes. They are used to determine whether a user can access a particular route or not. If you need to display or hide single elements within a component based on roles, I would recommend using *ngIf
to render UI elements based on conditions.
If you want to create a Guard based on roles (not just checking if a user is authenticated), you can implement something like this:
import { Injectable } from "@angular/core";
import { AuthService, CurrentUserService } from "app/shared/services";
import { Router, RouterStateSnapshot, ActivatedRouteSnapshot, CanActivate } from "@angular/router";
import { AspNetUsersDTO } from "app/shared/models";
import { Observable } from "rxjs/Rx";
@Injectable()
export class RoleGuard implements CanActivate {
constructor(private authService: AuthService,
private _currentUser: CurrentUserService,
private router: Router) {
}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> {
return new Promise<boolean>((resolve, reject) => {
if (!this.authService.isLoggedIn()) {
resolve(false);
return;
}
var currentUser: AspNetUsersDTO = new AspNetUsersDTO();
this._currentUser.GetCurrentUser().then((resp) => {
currentUser = resp;
let userRole = currentUser.roles && currentUser.roles.length > 0 ? currentUser.roles[0].toUpperCase() : '';
let roles = route && route.data["roles"] && route.data["roles"].length > 0 ? route.data["roles"].map(xx => xx.toUpperCase()) : null;
if (roles == null || roles.indexOf(userRole) != -1) resolve(true);
else {
resolve(false);
this.router.navigate(['login']);
}
}).catch((err) => {
reject(err);
this.router.navigate(['login']);
});
});
}
canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> {
return new Promise<boolean>((resolve, reject) => {
if (!this.authService.isLoggedIn()) {
resolve(false);
return;
}
var currentUser: AspNetUsersDTO = new AspNetUsersDTO();
this._currentUser.GetCurrentUser().then((resp) => {
currentUser = resp;
let userRole = currentUser.roles && currentUser.roles.length > 0 ? currentUser.roles[0].toUpperCase() : '';
let roles = route && route.data["roles"] && route.data["roles"].length > 0 ? route.data["roles"].map(xx => xx.toUpperCase()) : null;
if (roles == null || roles.indexOf(userRole) != -1) resolve(true);
else {
resolve(false);
this.router.navigate(['login']);
}
}).catch((err) => {
reject(err);
this.router.navigate(['login']);
});
});
}
}
You can then use this Guard in your routing configuration like this:
{
path: 'awards-team',
component: AwardsTeamComponent,
canActivateChild: [RoleGuard],
children: [
{
path: 'admin',
component: TeamComponentsAdminComponent,
data: { roles: ['super-admin', 'admin', 'user'] }
},
{
path: 'user',
component: TeamComponentsUserComponent,
data: { roles: ['user'] }
}
]
}