3d cartoon hands holding a phone

Unlock full course by purchasing a membership

Lesson 11

Protecting Routes with Guards in Angular

Preventing access to particular pages

EXTENDED

Protecting Routes with Guards in Angular

The last feature we are going to add is to prevent unauthenticated users from getting to the home page, and to auto re-redirect logged in users to the home page. Firebase will remember users automatically, so if we are already logged in we should go directly to the home page.

IMPORTANT: The guards feature I am about to show you is for user experience only. These guards are implemented client side and would not stop a malicious user from getting to any page they like. If you need to restrict certain users from accessing certain things, this needs to happen on the backend - i.e. we should never load the data into the application in the first place. A route guard like the one we are implementing will not stop a malicious user from accessing a route. This is why we have things like our Firestore Security Rules. It doesn’t matter if a malicious user hacks their way past our route guard to gain access to the main /home page without logging in, as no data will load in from Firebase if they haven’t authenticated. They will be on the /home page, but it will be empty.

Create a Guard for the Login Page

Create a file at src/app/shared/guards/login.guard.ts and add the following:

import { Injectable } from '@angular/core';
import { CanActivate } from '@angular/router';
import { NavController } from '@ionic/angular';
import { map, tap } from 'rxjs/operators';
import { AuthService } from '../data-access/auth.service';

@Injectable()
export class CanActivateLogin implements CanActivate {
  constructor(
    private authService: AuthService,
    private navCtrl: NavController
  ) {}

  canActivate() {
    return this.authService.user$.pipe(
      map((user) => (user ? false : true)),
      tap((canActivate) => {
        if (!canActivate) {
          this.navCtrl.navigateForward('/home');
        }
      })
    );
  }
}

The general idea here is that we implement the CanActivate interface. This means we need to supply a canActivate method. We have this method return an observable that emits true or false, and that will determine if the user is allowed to access the route or not. In this case, if the user can not activate the /login route it is because they are already logged in, and so we navigate them to the home page.

To use this guard, we can supply it to our route.

Modify the login route in app-routing.module.ts to use the guard:

  {
    path: 'login',
    canActivate: [CanActivateLogin],
    loadChildren: () =>
      import('./login/login.component').then((m) => m.LoginComponentModule),
  },
EXTENDED
Key

Thanks for checking out the preview of this lesson!

You do not have the appropriate membership to view the full lesson. If you would like full access to this module you can view membership options (or log in if you are already have an appropriate membership).