Route Guards (Protrecting Routes)

In an enterprise application, you absolutely cannot let malicious or unauthenticated users navigate to administrative pages like /dashboard. Because Angular is a Client-Side SPA, users have physical access to the browser URL bar. To stop them from forcing access, Angular provides Route Guards.

What is a Route Guard?

A Route Guard is simply a function (or a Service class) that returns true or false. If it returns true, the Router allows the user to proceed. If it returns false, the Router instantly cancels the navigation.

Types of Route Guards

  • CanActivate: Verifies if a user is allowed to navigate into a route.
  • CanDeactivate: Verifies if a user is allowed to navigate away from a route (useful to warn users about unsaved form data).
  • CanMatch / CanLoad: Prevents lazy-loaded modules from even downloading into the browser if the user isn't authorized to see them.

Writing a Modern Functional Guard (CanActivate)

Historically, guards were defined as classes using `@Injectable`. In modern Angular 15+, they can be much simpler standalone Functions!

// auth.guard.ts
import { inject } from '@angular/core';
import { Router, CanActivateFn } from '@angular/router';
import { AuthService } from './auth.service';

export const authGuard: CanActivateFn = (route, state) => {
  // We use inject() to get access to our Services
  const authService = inject(AuthService);
  const router = inject(Router);

  // If the user is logged in, allow them to pass!
  if (authService.isLoggedIn()) {
    return true; 
  }

  // Otherwise, bounce them to the login page and block access
  router.navigate(['/login']);
  return false;
};

Applying the Guard in Route Configuration

Once your Guard function is written, you explicitly attach it to the sensitive routes in your app.routes.ts configuration array.

import { Routes } from '@angular/router';
import { DashboardComponent } from './dashboard/dashboard.component';
import { LoginComponent } from './login/login.component';
import { authGuard } from './auth.guard'; // Import your guard

export const routes: Routes = [
  { path: 'login', component: LoginComponent },
  { 
    path: 'dashboard', 
    component: DashboardComponent,
    canActivate: [authGuard] // <-------- Guard is active!
  }
];

Security Warning

Client-side Route Guards improve the User Experience (UX). They are NOT absolute security. A malicious hacker with Developer Tools can bypass Javascript and force the router. You must ALWAYS secure your actual Backend Database APIS with real JWT verification. Do not rely entirely on the frontend!

Conclusion

You now have a secure, navigable SPA architecture. Next, we need to allow the user to input data into the application securely using Angular's incredibly powerful Forms system, starting with Template-Driven Forms.