Introduction
In modern web applications, securing routes and components based on user roles is essential. Role-Based Access Control (RBAC) is a strategy that allows or restricts users from accessing parts of an application based on their assigned roles.
In this article, you'll learn how to implement RBAC in Angular using route guards, services, and role-based logic to control access across your application.
What is RBAC?
Role-Based Access Control is a security mechanism that,
- Assigns users to roles (like Admin, Editor, User).
- Defines permissions for each role.
- Restricts or allows access to routes, components, or actions based on the user’s role.
Prerequisites
Before implementing RBAC, ensure,
- You have authentication set up (e.g., JWT-based login).
- Roles are retrievable from the backend or the token.
- Angular project is initialized with routing (@angular/router).
Step-by-Step Implementation
1. Define Roles and User Model.
// user.model.ts
export interface User {
username: string;
token: string;
roles: string[]; // e.g., ['Admin', 'User']
}
2. Authentication Service with Role Info.
// auth.service.ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class AuthService {
private currentUser: User | null = null;
constructor() {
const userData = localStorage.getItem('user');
if (userData) {
this.currentUser = JSON.parse(userData);
}
}
getUser(): User | null {
return this.currentUser;
}
hasRole(role: string): boolean {
return this.currentUser?.roles.includes(role) ?? false;
}
hasAnyRole(roles: string[]): boolean {
return roles.some(role => this.hasRole(role));
}
}
3. Create a Role Guard.
// role.guard.ts
import { Injectable } from '@angular/core';
import {
CanActivate,
ActivatedRouteSnapshot,
RouterStateSnapshot,
Router
} from '@angular/router';
import { AuthService } from './auth.service';
@Injectable({
providedIn: 'root'
})
export class RoleGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) {}
canActivate(route: ActivatedRouteSnapshot): boolean {
const expectedRoles = route.data['roles'] as string[];
if (this.authService.hasAnyRole(expectedRoles)) {
return true;
}
// Redirect to access denied or login
this.router.navigate(['/access-denied']);
return false;
}
}
4. Use the Role Guard in Routes.
// app-routing.module.ts
const routes: Routes = [
{
path: 'admin',
component: AdminDashboardComponent,
canActivate: [RoleGuard],
data: { roles: ['Admin'] }
},
{
path: 'editor',
component: EditorComponent,
canActivate: [RoleGuard],
data: { roles: ['Editor', 'Admin'] }
},
{
path: 'access-denied',
component: AccessDeniedComponent
}
];
5. Show/Hide UI Based on Roles (Optional).
<!-- in component template -->
<div *ngIf="authService.hasRole('Admin')">
<button>Edit Settings</button>
</div>
Best Practices for Angular RBAC
- Always secure routes with guards; never rely solely on front-end UI logic.
- Store roles securely (e.g., in JWT tokens, not just localStorage).
- Refresh user roles upon login or token refresh.
- Keep RBAC logic centralized inside services and guards.
- Pair RBAC with backend authorization to fully protect APIs.
Conclusion
Implementing RBAC in Angular ensures that your application is secure, maintainable, and scalable. Using route guards, role-aware services, and conditional templates, you can easily control who gets access to what.
With this setup, you now have a robust way to protect routes and features based on user roles in your Angular apps.
Happy coding !!