Search⌘ K
AI Features

Auth Guard

Understand how to implement Angular AuthGuard for route protection by leveraging authentication checks. Learn to create tests for AuthGuard using mock dependencies to verify route access and redirects without relying on TestBed.

With our new service method, we can move on to the route guard itself. We’ll implement the guard before we approach the test. We’ll address the test later, because we’ll take a slightly different approach to how we test this service.

This is our updated code:

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "lets-get-lunch": {
      "projectType": "application",
      "schematics": {},
      "root": "",
      "sourceRoot": "src",
      "prefix": "app",
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "dist/lets-get-lunch",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "tsconfig.app.json",
            "aot": true,
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ],
            "styles": [
              "node_modules/bootstrap/dist/css/bootstrap.min.css",
              "src/styles.css"
            ],
            "scripts": [
              "node_modules/jquery/dist/jquery.min.js",
              "node_modules/bootstrap/dist/js/bootstrap.min.js"
            ]
          },
          "configurations": {
            "production": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ],
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "extractCss": true,
              "namedChunks": false,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true,
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "2mb",
                  "maximumError": "5mb"
                },
                {
                  "type": "anyComponentStyle",
                  "maximumWarning": "6kb",
                  "maximumError": "10kb"
                }
              ]
            }
          }
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "browserTarget": "lets-get-lunch:build"
          },
          "configurations": {
            "production": {
              "browserTarget": "lets-get-lunch:build:production"
            }
          }
        },
        "extract-i18n": {
          "builder": "@angular-devkit/build-angular:extract-i18n",
          "options": {
            "browserTarget": "lets-get-lunch:build"
          }
        },
        "test": {
          "builder": "@angular-devkit/build-angular:karma",
          "options": {
            "main": "src/test.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "tsconfig.spec.json",
            "karmaConfig": "karma.conf.js",
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ],
            "styles": [
              "node_modules/bootstrap/dist/css/bootstrap.min.css",
              "src/styles.css"
            ],
            "scripts": [
              "node_modules/jquery/dist/jquery.min.js",
"node_modules/bootstrap/dist/js/bootstrap.min.js"
            ]
          }
        },
        "lint": {
          "builder": "@angular-devkit/build-angular:tslint",
          "options": {
            "tsConfig": [
              "tsconfig.app.json",
              "tsconfig.spec.json",
              "e2e/tsconfig.json"
            ],
            "exclude": [
              "**/node_modules/**"
            ]
          }
        },
        "e2e": {
          "builder": "@angular-devkit/build-angular:protractor",
          "options": {
            "protractorConfig": "e2e/protractor.conf.js",
            "devServerTarget": "lets-get-lunch:serve"
          },
          "configurations": {
            "production": {
              "devServerTarget": "lets-get-lunch:serve:production"
            }
          }
        }
      }
    }
  },
  "defaultProject": "lets-get-lunch"
}
Auth guard

AuthGuard implementation

  1. First we need to update the imports within AuthGuard from @angular/router to include Router.
TypeScript 3.3.4
// src/app/guards/auth/auth.guard.ts
import {
CanActivate,
ActivatedRouteSnapshot,
RouterStateSnapshot,
UrlTree,
Router
} from '@angular/router';
  1. Import AuthService so that we can use the new method we just created.
TypeScript 3.3.4
// src/app/guards/auth/auth.guard.ts
import { AuthService } from '../../services/auth/auth.service';
  1. Create a constructor and inject our two dependencies.
TypeScript 3.3.4
// src/app/guards/auth/auth.guard.ts
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 {
return true;
}
}
  1. While we’re at it, also remove the two parameters from the canActivate method and update its return
...