← Back to Chapters

Role Guard Routing & Conditional Routing

?️ Role Guard Routing & Conditional Routing

? Quick Overview

In Angular, route guards are used to control navigation between routes. With Role Guards, you can allow or block access based on user roles (for example: admin, user).
Conditional Routing lets you dynamically redirect or block users depending on conditions like authentication, permissions, or application state.

? Key Concepts

  • Route Guard – A class that decides if a route can be activated, loaded, or left.
  • CanActivate – Guard interface that runs before a route activates.
  • Role-based access – Only users with specific roles (e.g., admin) can open protected routes.
  • Conditional navigation – Components can navigate users to different pages depending on their role or state.
  • Forbidden routes – Users without permission are redirected to a safe route (like /forbidden).

? Syntax & Theory

A typical role guard in Angular:

  • Implements CanActivate from @angular/router.
  • Injects an AuthService (or similar) to know the current user role.
  • Returns true when navigation is allowed, otherwise redirects and returns false.
  • Is applied to routes using the canActivate property in the route configuration.

? Code Example: Auth Service

This service stores and exposes the current user role for the whole application.

? View Code Example
// auth.service.ts - manages current user role
import { Injectable } from '@angular/core';

@Injectable({ providedIn: 'root' })
export class AuthService {
  private userRole: string = 'user'; // default role for demonstration

  getRole(): string {
    return this.userRole;
  }

  isAdmin(): boolean {
    return this.userRole === 'admin';
  }

  setRole(role: string) {
    this.userRole = role; // dynamically set the role during login
  }
}

? Code Example: Role Guard

The role guard only allows admins to access the protected route and redirects others.

? View Code Example
// role.guard.ts - only allows admins to activate certain routes
import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';
import { AuthService } from './auth.service';

@Injectable({ providedIn: 'root' })
export class RoleGuard implements CanActivate {
  constructor(private auth: AuthService, private router: Router) {}

  canActivate(): boolean {
    if (this.auth.isAdmin()) {
      return true; // user is admin, allow navigation
    }
    this.router.navigate(['/forbidden']); // not admin, redirect to forbidden page
    return false;
  }
}

?️ Code Example: Applying Guard in Routes

Attach the RoleGuard to your routes using the canActivate property.

? View Code Example
// app.routes.ts - protect the dashboard route using RoleGuard
import { Routes } from '@angular/router';
import { DashboardComponent } from './dashboard/dashboard.component';
import { RoleGuard } from './role.guard';

export const routes: Routes = [
  {
    path: 'dashboard',
    component: DashboardComponent,
    canActivate: [RoleGuard] // only admins can open this route
  },
  {
    path: 'forbidden',
    loadComponent: () =>
      import('./forbidden/forbidden.component').then(m => m.ForbiddenComponent) // standalone: true on component
  }
];

? Code Example: Conditional Routing on Login

The login component decides where to navigate after login based on the user role, using conditional routing.

? View Code Example
// login.component.ts - navigate differently for admin vs normal user
import { Component } from '@angular/core';
import { Router } from '@angular/router';
import { AuthService } from '../auth.service';

@Component({
  selector: 'app-login',
  template: `<button (click)="login()">Login</button>`
})
export class LoginComponent {
  constructor(private auth: AuthService, private router: Router) {}

  login() {
    if (this.auth.isAdmin()) {
      this.router.navigate(['/dashboard']); // admin goes to dashboard
    } else {
      this.router.navigate(['/forbidden']); // non-admin goes to forbidden page
    }
  }
}

? Live Flow / Explanation

How Role Guard Routing Works Step-by-Step

  1. The user tries to navigate to /dashboard.
  2. Angular checks the RoleGuard because it is listed in canActivate for that route.
  3. RoleGuard calls auth.isAdmin() from AuthService.
  4. If the user role is admin, the guard returns true and navigation continues.
  5. If the user is not an admin, the guard:
    • Redirects the user to /forbidden.
    • Returns false, so /dashboard is never activated.
  6. On login, LoginComponent uses conditional routing:
    • Admins go to /dashboard.
    • Non-admins go to /forbidden.

This combination of route guards and conditional navigation helps you protect sensitive pages and provide a better user experience.

✅ Tips & Best Practices

  • Create separate guards for different roles (for example, AdminGuard, UserGuard) for clarity.
  • Store roles securely using mechanisms like JWT tokens or secure storage, not hard-coded values.
  • Combine guards with lazy-loaded feature modules to improve performance and security.
  • Always mirror frontend guards with backend authorization checks to fully protect sensitive data.

? Try It Yourself / Practice

  • Create a ModeratorGuard that only allows moderators to access a /moderation route.
  • Implement a /profile route that conditionally shows extra admin controls if the user is an admin.
  • Extend AuthService to simulate login/logout and dynamically change roles, then test routing behavior.
  • Add a reusable canMatch guard to prevent entire feature modules from loading for certain roles.