Reputation: 105
I am using Angular and this is for my authentication check:
export class EnsureAuthenticated implements CanActivate {
constructor(private auth: AuthService, private router: Router) {}
canActivate(): boolean {
if (localStorage.getItem('token')) {
return true;
}
else {
this.router.navigateByUrl('/login');
return false;
}
}
}
{
path: 'path',
component: myComponent,
canActivate: [EnsureAuthenticated]
}
It's working fine but my problem is this page can be accessed by both user and admin.
I know I didn't set any condition on it. How do I set the proper condition on it?
I don't want to access this page to admin
Upvotes: 2
Views: 7478
Reputation: 3089
See this example in stackblitz
In your app-routing.module.ts
const routes: Routes = [
{
path: "admin",
component: AdminOnlyComponent,
canActivate: [RoleGuardService],
data: { roles: ['admin']}
},
...
}
In your RoleGuardService
import { Injectable } from '@angular/core';
import { UserRolesService} from './user-roles.service';
import { Router, ActivatedRouteSnapshot } from '@angular/router';
@Injectable({
providedIn: 'root'
})
export class RoleGuardService {
constructor(private getUserRoles: UserRolesService) { }
canActivate(route: ActivatedRouteSnapshot): boolean {
return route.data.roles.some( ai => this.getUserRoles.getRoles().includes(ai) );
}
}
In UserRolesService
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class UserRolesService {
userRoles: string[] = [];
constructor() { }
setRoles(Roles: string[]){
this.userRoles = Roles.slice(0);
}
getRoles(){
return this.userRoles;
}
}
Set roles when user logged in to the system or get those roles from your localstorage....
Upvotes: 5
Reputation: 564
You should create a RoleGuardService, that expect a role from a user and check if this role is equal of the role espected, like this:
constructor(public auth: AuthService, public router: Router) {}
canActivate(route: ActivatedRouteSnapshot): boolean {
// this will be passed from the route config
// on the data property
const expectedRole = route.data.expectedRole;
const token = localStorage.getItem('token');
// decode the token to get its payload
const tokenPayload = decode(token);
if (
!this.auth.isAuthenticated() ||
tokenPayload.role !== expectedRole
) {
this.router.navigate(['login']);
return false;
}
return true;
}
And protect yout routing by user roles guard like:
{
path: 'admin',
component: AdminComponent,
canActivate: [RoleGuard],
data: {
expectedRole: 'admin'
}
},
This scenario assumes that you are using a custom role claim in your JWT, for further information i advice you to read that article that explain perfectly your answer: https://medium.com/@ryanchenkie_40935/angular-authentication-using-route-guards-bf7a4ca13ae3
Upvotes: 0
Reputation: 554
Assuming that you have a service to retrieve the connected user's role, you just have to check that role and return false if the user is an admin to prevent that kind of users to have access to your pages. If the token you store in the lcoal storage is a JWT token, sometimes the user role is encoded into it, you have to decode the token to extract the role.
Upvotes: 0