Route Guards Based on Permission in Angular (Enterprise)
Route Guards Based on Permission in Angular (Enterprise)
This setup includes:
- ✔ Prevent user from opening URL directly
- ✔ Redirect to 403 Forbidden page
- ✔ Supports roles + permissions
- ✔ Works with lazy loaded modules
1️⃣ Create Forbidden Component (403 Page)
// forbidden.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-forbidden',
template: `
403 - Forbidden
You don’t have permission to access this page.
`
})
export class ForbiddenComponent {}
2️⃣ Add Route Data (Permission Required)
// app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { ForbiddenComponent } from './forbidden.component';
import { PermissionGuard } from './core/auth/permission.guard';
const routes: Routes = [
{
path: 'dashboard',
canActivate: [PermissionGuard],
data: { permissions: ['DASHBOARD_VIEW'] },
loadComponent: () => import('./pages/dashboard/dashboard.component').then(m => m.DashboardComponent)
},
{
path: 'users',
canActivate: [PermissionGuard],
data: { permissions: ['USERS_VIEW'] },
loadChildren: () => import('./pages/users/users.module').then(m => m.UsersModule)
},
{ path: 'forbidden', component: ForbiddenComponent },
{ path: '**', redirectTo: 'dashboard' }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule {}
3️⃣ Permission Guard (Enterprise)
// permission.guard.ts
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, Router } from '@angular/router';
import { PermissionService } from './permission.service';
import { Permission } from './permission.model';
@Injectable({ providedIn: 'root' })
export class PermissionGuard implements CanActivate {
constructor(
private permissionService: PermissionService,
private router: Router
) {}
canActivate(route: ActivatedRouteSnapshot): boolean {
const requiredPermissions = route.data['permissions'] as Permission[];
// if no permission required, allow
if (!requiredPermissions || requiredPermissions.length === 0) {
return true;
}
const allowed = this.permissionService.hasAnyPermission(requiredPermissions);
if (!allowed) {
this.router.navigate(['/forbidden']);
return false;
}
return true;
}
}
4️⃣ Secure Child Routes also (Best Practice)
For nested routes, use canActivateChild:
// permission.guard.ts (upgrade)
import { CanActivateChild } from '@angular/router';
export class PermissionGuard implements CanActivate, CanActivateChild {
canActivateChild(route: ActivatedRouteSnapshot): boolean {
return this.canActivate(route);
}
}
// Usage in routing
{
path: 'users',
canActivateChild: [PermissionGuard],
data: { permissions: ['USERS_VIEW'] },
children: [
// child routes here
]
}
5️⃣ Lazy Loaded Module Protection
// users-routing.module.ts
const routes: Routes = [
{
path: '',
canActivate: [PermissionGuard],
data: { permissions: ['USERS_VIEW'] },
component: UsersListComponent
},
{
path: 'create',
canActivate: [PermissionGuard],
data: { permissions: ['USERS_CREATE'] },
component: UsersCreateComponent
}
];
🔥 Interview Explanation (Perfect)
Q) How do you stop user from accessing URL directly?
- ✅ I use a Route Guard and check required permissions from
route.data. - ✅ If permission is missing, I redirect to
/forbidden.
Q) Why still need guard if menu is hidden?
- ✅ Hiding menu is only UI security.
- ✅ Guard ensures frontend route-level protection similar to backend authorization.
Comments
Post a Comment