Introduction
Route Guards in Angular are used to control access to routes based on certain conditions. They are essential for implementing authentication and authorization in your Angular applications. Route Guards can prevent users from navigating to certain routes or redirect them to other routes based on specific criteria.
Types of Route Guards
Angular provides several types of route guards:
- CanActivate: Determines if a route can be activated.
- CanActivateChild: Determines if a child route can be activated.
- CanDeactivate: Determines if a route can be deactivated.
- CanLoad: Determines if a module can be loaded.
- Resolve: Pre-fetches data before activating a route.
Implementing CanActivate Guard
Step-by-Step Guide
-
Create a Guard Service: Use Angular CLI to generate a guard service.
ng generate guard auth
-
Implement CanActivate Interface: Modify the generated guard service to implement the
CanActivate
interface.import { Injectable } from '@angular/core'; import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree } from '@angular/router'; import { Observable } from 'rxjs'; import { AuthService } from './auth.service'; // Assume you have an AuthService @Injectable({ providedIn: 'root' }) export class AuthGuard implements CanActivate { constructor(private authService: AuthService) {} canActivate( next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree { return this.authService.isLoggedIn(); // Replace with your actual authentication logic } }
-
Update Routing Module: Apply the guard to the routes in your routing module.
import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { HomeComponent } from './home/home.component'; import { LoginComponent } from './login/login.component'; import { AuthGuard } from './auth.guard'; const routes: Routes = [ { path: 'home', component: HomeComponent, canActivate: [AuthGuard] }, { path: 'login', component: LoginComponent }, { path: '', redirectTo: '/home', pathMatch: 'full' } ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }
Example: AuthService
Here is a simple example of an AuthService
that the guard might use.
import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class AuthService { private loggedIn = false; constructor() { } isLoggedIn(): boolean { return this.loggedIn; } login(): void { this.loggedIn = true; } logout(): void { this.loggedIn = false; } }
Practical Exercise
Task
- Create a new Angular project.
- Implement an
AuthGuard
that prevents access to aDashboardComponent
unless the user is logged in. - Create a simple
AuthService
to manage login state. - Add routes for
LoginComponent
andDashboardComponent
. - Apply the
AuthGuard
to theDashboardComponent
route.
Solution
-
Create a new Angular project:
ng new route-guards-demo cd route-guards-demo
-
Generate Components and Guard:
ng generate component login ng generate component dashboard ng generate guard auth
-
Implement AuthService:
// src/app/auth.service.ts import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class AuthService { private loggedIn = false; isLoggedIn(): boolean { return this.loggedIn; } login(): void { this.loggedIn = true; } logout(): void { this.loggedIn = false; } }
-
Implement AuthGuard:
// src/app/auth.guard.ts import { Injectable } from '@angular/core'; import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, Router } from '@angular/router'; import { Observable } from 'rxjs'; import { AuthService } from './auth.service'; @Injectable({ providedIn: 'root' }) export class AuthGuard implements CanActivate { constructor(private authService: AuthService, private router: Router) {} canActivate( next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree { if (this.authService.isLoggedIn()) { return true; } else { this.router.navigate(['/login']); return false; } } }
-
Update Routing Module:
// src/app/app-routing.module.ts import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { LoginComponent } from './login/login.component'; import { DashboardComponent } from './dashboard/dashboard.component'; import { AuthGuard } from './auth.guard'; const routes: Routes = [ { path: 'login', component: LoginComponent }, { path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard] }, { path: '', redirectTo: '/login', pathMatch: 'full' } ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }
-
Add Login Logic:
// src/app/login/login.component.ts import { Component } from '@angular/core'; import { Router } from '@angular/router'; import { AuthService } from '../auth.service'; @Component({ selector: 'app-login', templateUrl: './login.component.html', styleUrls: ['./login.component.css'] }) export class LoginComponent { constructor(private authService: AuthService, private router: Router) { } login() { this.authService.login(); this.router.navigate(['/dashboard']); } }
<!-- src/app/login/login.component.html --> <button (click)="login()">Login</button>
Conclusion
Route Guards are a powerful feature in Angular that help you control access to different parts of your application. By implementing guards like CanActivate
, you can ensure that only authenticated users can access certain routes, enhancing the security and user experience of your application. In this section, you learned how to create and apply a simple AuthGuard
to protect routes in your Angular application.
Angular 2+ Course
Module 1: Introduction to Angular
Module 2: TypeScript Basics
- Introduction to TypeScript
- TypeScript Variables and Data Types
- Functions and Arrow Functions
- Classes and Interfaces