May 2, 2025
|
7
mins

Route Guards in Angular: Secure Your Application

In Angular, Route Guards are used to control the access of users to certain routes based on defined conditions. They act as gatekeepers, ensuring that users meet specific requirements before navigating to a route.

Uses of  Angular Route Guards

  • To confirm the navigational operation
  • Asking whether to save before moving away from a view
  • Allow access to certain parts of the application to specific users
  • Validating the route parameters before navigating to the route
  • Fetching some data before you display the component.

Types of Route Guards

The Angular Router supports six different guards, which you can use to protect the route.

  1. CanActivate
  2. CanDeactivate
  3. Resolve
  4. CanLoad
  5. CanActivateChild
  6. CanMatch

CanActivate

The Angular CanActivate guard decides if a route can be activated (or the component gets rendered). We use this guard when we want to check a condition, before activating the component or showing it to the user. This allows us to cancel the navigation.

Use cases

  • Checking if a user has logged in
  • Checking if a user has permission

One of the use cases of this guard is to check if the user has logged in to the system. If the user has not logged in, then the guard can redirect them to the login page.

CanDeactivate

This Angular Guard decides if the user can leave the component (navigate away from the current route). This route is useful when the user might have some pending changes which is not yet saved. The CanDeactivate route allows us to ask for user confirmation before leaving the component. You might ask the user if it’s OK to discard pending changes rather than save them.

How CanDeactivate Works

  1. It uses the CanDeactivate interface that requires the implementation of a canDeactivate() method.
  2. The method can return:
    • true: Allow navigation.
    • false: Prevent navigation.
    • Observable<boolean>: Perform asynchronous checks (e.g., API call).
    • Promise<boolean>: Handle async operations before making a decision.

Additional Use Cases

  • Preventing users from leaving while a file is uploading.
  • Confirming navigation during a sensitive operation (e.g., payment process).
  • Blocking navigation if a background API call is in progress.
  • CanDeactivate guards improve user experience by preventing accidental data loss.
  • Always ensure the guard logic is clear and user-friendly, using confirmation dialogs when necessary.
  • Combine with other guards (CanActivate, Resolve) for robust route management.

Resolve

This guard delays the activation of the route until some tasks are complete. You can use the guard to pre-fetch the data from the backend API before activating the route.

When to Use Resolve Guard?

  • When you need to fetch data from an API before showing a component.
  • To ensure data consistency before rendering the component.
  • When dealing with routes that depend on large datasets.

How Resolve Works

  1. The Resolve Guard fetches data using a service.
  2. The route is activated only after data is fetched successfully.
  3. Data is made available to the component using ActivatedRoute.

CanLoad

The CanLoad Guard prevents the loading of the LazyLoaded Module. We generally use this guard when we do not want to unauthorized users to be able even to see the source code of the module.

This guard works similarly to CanActivate guard with one difference. The CanActivate guard prevents a particular route from being accessed. The CanLoad prevents the entire lazy-loaded module from being downloaded, protecting all the routes within that module.

When to Use CanLoad?

  • To restrict access to lazy-loaded modules for unauthorized users.
  • To prevent loading of modules based on user roles or permissions.
  • To reduce bandwidth usage by avoiding unnecessary downloads of large files.
  • For security purposes to ensure modules are not even downloaded if access is denied.

How CanLoad Works

  1. CanLoad implements the CanLoad interface, which requires the canLoad() method.
  2. It returns one of the following:
    • true: Module can be loaded.
    • false: Prevent module from loading.
    • Observable<boolean> or Promise<boolean>: For async checks (e.g., API call).

Differences Between CanActivate and CanLoad

Preview of image

CanActivateChild

CanActivateChild guard determines whether a child route can be activated. This guard is very similar to CanActivateGuard. We apply this guard to the parent route. The Angular invokes this guard whenever the user tries to navigate to any of its child routes. This allows us to check some conditions and decide whether to proceed with the navigation or cancel it.

How to Build Angular Route Guards

Building the Guards is very easy.

  1. Build the Guard as Service.
  2. Implement the Guard Method in the Service
  3. Register the Guard Service in the Root Module
  4. Update the Routes to use the guards

1. Build the Guard as a Service

Building the Guard Service is as simple as building any other Angular Service. You need to import the corresponding guard from the Angular Router Library using the Import statement. For Example use CanActivate Guard import the CanActivate in the import  the CanActivate in the import statement

import { CanActivate } from '@angular/router';

Next, create the Guard class, which implements the selected guard Interface as shown below.

@Injectable() 

export class ProductGuardService implements CanActivate {} 

2. Implement the Guard Method

The next step is to create the Guard Method. The name of the Guard method is the same as the Guard it implements. For Example, to implement the CanActivate guard, create a method CanActivate

canActivate(): boolean {     

    // Check weather the route can be activated;     

    return true;      

    // or false if you want to cancel the navigation;  

} 

The return value from the Guard

The guard method must return either a True or a False value.

If it returns true, the navigation process continues. if it returns false, the navigation process stops, and the user stays put.

The above method returns a True value. The Guard can also return an Observable or a Promise, which eventually returns a True or false. The Angular will keep the user waiting until the guard returns true or false.

The guard can also tell the router to navigate elsewhere, effectively canceling the current navigation.

3. Register the Guard as Service in Module

As mentioned earlier, guards are nothing but services. We need to register them with the providers array of the Angular Module as shown below.

providers: [ProductService,ProductGuardService]

4. Update the Routes

{ path: 'product', component: ProductComponent, canActivate : [ProductGuardService]  

} 

The above code adds the canActivate guard (ProductGuardService) to the  Product route.

When the user navigates to the Product route, Angular calls the canActivate method from the ProductGuardService. If the method returns true, then the ProductComponent is rendered.

You can add more than one guard, as shown below

{ path: 'product',  

  component: ProductComponent,  

  canActivate : [ProductGuardService, AnotherProductGuardService ]  

} 

Order of execution of route guards

A route can have multiple guards, and you can have guards at every level of a routing hierarchy.

  1. CanDeactivate() and CanActivateChild() guards are always checked first. The checking starts from the deepest child route to the top.
  2. CanActivate() Guard is checked next, and checking starts from the top to the deepest child route.
  3. CanLoad() Is invoked next If the feature module is to be loaded asynchronously.
  4. Resolve() Guard is invoked last.

The Angular Router cancels the navigation If any of the guards return false.

Angular Guards ExampleGuard Service

We create Guard classes as a service. Create a file named product-guard.service.ts in the src/app folder and add the following code

import { Injectable } from '@angular/core'; 

import { Router, CanActivate, ActivatedRouteSnapshot,RouterStateSnapshot } from '@angular/router'; 

  

@Injectable() 

export class ProductGuardService implements CanActivate { 

  

  constructor(private _router:Router ) {       

  }       

  

  canActivate(route: ActivatedRouteSnapshot, 

              state: RouterStateSnapshot): boolean { 

      console.log("canActivate");      //return true     

     //remove comments to return true               

     alert('You are not allowed to view this page. You are redirected to Home Page');  

     this._router.navigate(["home"]);              

     return false;      

} } 

The canActivate method accepts two arguments. The first argument is an ActivatedRouteSnapshot object, which describes the route that is being navigated to using the properties. The second argument is a RouterStateSnapshot object, which describes the current route through a single property called URL.

canActivate(route: ActivatedRouteSnapshot,  

           state: RouterStateSnapshot): boolean {     

  

    console.log("canActivate");     //return true  

    //remove comments to return true    

    alert('You are not allowed to view this page. You are redirected to Home Page');     

    //this._router.navigate(["home"]); //navigate to some other route;     

    return false; 

} 

Import the Guard in the Root Module

import { BrowserModule } from '@angular/platform-browser'; 

import { NgModule } from '@angular/core'; 

import { FormsModule } from '@angular/forms'; 

import { HttpModule } from '@angular/http'; 

import { RouterModule } from '@angular/router'; 

import { AppComponent } from './app.component'; 

import { HomeComponent} from './home.component'; 

import { ContactComponent} from './contact.component'; 

import { ProductComponent} from './product.component'; 

import { ErrorComponent} from './error.component'; 

import { ProductDetailComponent} from './product-detail.component'; 

import { ProductService } from './product.service'; 

import { ProductGuardService } from './product-guard.service'; 

import { appRoutes } from './app.routes'; 

  

@NgModule({ 

  declarations: [ AppComponent,HomeComponent,ContactComponent,  

                 ProductComponent,ErrorComponent,  

                 ProductDetailComponent],      

  imports:      [ BrowserModule, FormsModule,HttpModule,                 

                 RouterModule.forRoot(appRoutes)],      

  providers:    [ ProductService,ProductGuardService ],  

  bootstrap:    [ AppComponent] 

}) 

export class AppModule { } 

First, Import the Guard Service as shown below

import { ProductGuardService } from './product-guard.service'; 

Next, Register it using the Providers metadata so that that router can use it. Remember that Guards must be provided at the angular module level

providers: [ProductService,ProductGuardService],

Update the Routes

Finally, Update the app.routes class

import { Routes } from '@angular/router';  

import { HomeComponent} from './home.component'; 

import { ContactComponent} from './contact.component'; 

import { ProductComponent} from './product.component'; 

import { ErrorComponent} from './error.component'; 

import { ProductDetailComponent} from './product-detail.component'; 

import { ProductGuardService } from './product-guard.service'; 

  

export const appRoutes: Routes = [      

  { path: 'home', component: HomeComponent },      

  { path: 'contact', component: ContactComponent },      

  { path: 'product', component: ProductComponent, canActivate :[ProductGuardService] },      

  { path: 'product/:id', component: ProductDetailComponent },      

  { path: '', redirectTo: 'home', pathMatch: 'full' },      

  { path: '**', component: ErrorComponent } 

]; 

The only change we have made is to attach the ProductGuardService to the CanActivate guard

{ path: 'product',  

  component: ProductComponent,  

  canActivate : [ProductGuardService] }, 

Summary

The angular Guards are a great tool that helps us to protect the route. They also help us run some logic, get data from the back-end server, etc. You can also create multiple guards against a single route or use the same guard against multiple routes.

Other BLOGS