Home » Angular » How to create a router guard in Angular

How to create a router guard in Angular

In this tutorial, I will show you how to create a router guard in Angular 5. Protecting routes using router guards is a common thing in web application development. As a wonderful framework, Angular provides a very easiest way to create routes guards for your Angular project.

If you like to video tutorial, follow this.

Let’s start.

Notice: In this tutorial, I’m going to use a new angular application to create and demonstrate the routes guards. But, you can create your route guards for an existing project following this tutorial.

First of all, we need to create a new Angular application using Angular CLI. If you want to know how to create a fresh Angular application, follow this link.

‘ng serve –open’ command will run our new angular application in the browser. If your installation was successful, you can see the running application without errors.

Then, we have to create a login module, a dashboard module, and auth guard and auth service.

Notice: The login module and the dashboard module are optional. You can use your own modules as your choice. As an example, if you want to navigate the user to profile rather than the dashboard, you can execute the corresponding code snippet in the profile module.

To create above things, run following commands consecutively.

1. ng generate module login double dash routing.

(ng generate module login –routing)

2. ng generate component login.

(ng generate component login)

3. ng generate module dashboard double dash routing.

(ng generate module dashboard –routing)

4. ng generate component dashboard.

(ng generate component dashboard)

5. ng generate guard guards/auth.

(ng generate guard guards/auth)

6. ng generate service services/auth.

(ng generate service services/auth)

Then, open the app.component.html and remove all the code inside it by keeping the router-outlet tag and save changes. After doing this, the app.component.html file as follows.

<router-outlet></router-outlet>

Then, open the login.component.html file and create a login form. Here, I will create a login button in the login form. Add some styles to that form. After doing those things, login.component.html and login.component.scss files are as follows.

<div class="login-form">
  <!-- create your login form -->
  <button (click)=loginUser()>Login</button>
</div>
.login-form{
  margin-top: 50px;
  margin-bottom: 50px;
  margin-left: 200px;
  margin-right: 200px;
  padding: 100px;
  height: 500px;
  background-color: #f3f3f3;
}

login button for angula router guard tutorial

After clicking on the login button, the token will be saved in local storage and the user will be navigated to the dashboard. In this tutorials I use “my_token “as access token. In your case, it may be JWT token, OAuth token etc…

Then, set the router path in the login-routing.module.ts file. The code in the login-routing.modules.ts file is as follows.

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { LoginComponent } from './login.component';

const routes: Routes = [
  {
    path:'',
    component: LoginComponent
  }
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class LoginRoutingModule { }

Now, open the dashboard-routing.module.ts file and the set router path. Ater that the dashboard-routing.module.ts file is as follows.

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { DashboardComponent } from './dashboard.component';

const routes: Routes = [
  {
    path:'',
    component: DashboardComponent
  }
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class DashboardRoutingModule { }

Creating router guard

This is the time to set up the router guard. So, open the auth.service.ts file and create a rxjs behavior subject instance with the default value, false. Then, define the hasToken() method to check whether the current user has a token or not. Also, create the setLoggedIn() method to update logged-in status of logged-in-$ stream.  After doing those things, the auth.service.ts file is as follows.

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

@Injectable()
export class AuthService {

  loggenIn$ = new BehaviorSubject(false);

  constructor() { 

  	if(this.hasToken()){
  		this.setLoggedIn(true);
  	}else{

  		this.setLoggedIn(false);
  	}
  }

  hasToken() : boolean{

  	//chack user has a token
  	if(localStorage.getItem('token')){
  		return true;
  	}else{
  		return false;
  	}
  }

  setLoggedIn(value: boolean){
  	//update loggedin status in loggedIn$ stream. 
  	this.loggenIn$.next(value);
  }
}

Now we have to configure our auth guard. So, open the auth.guard.ts file and subscribe for the logged-in-$ stream. Also, define the loggen-in-status property with the default value, false and set new status to that property in call back function. After doing those things, the auth.gurad.ts file is as follows.

import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs/Observable';

//import auth service
import { AuthService } from '../services/auth.service';

@Injectable()
export class AuthGuard implements CanActivate {

  loggedInStatus : boolean = false;

  constructor(private authService : AuthService){}
  
  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {

  this.authService.loggenIn$.subscribe(
    (status) => {
      this.loggedInStatus = status;
    });  

  return this.loggedInStatus;	 
  }
}

Open the app.module.ts file and import the auth guard and the auth service. After that, auth guard.app.modules.ts file is as follows.

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

import { AppRoutingModule } from './app-routing.module';

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

//imort our guard and service
import { AuthService } from './services/auth.service';
import { AuthGuard } from './guards/auth.guard';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule
  ],
  providers: [ 
  	AuthService,
  	AuthGuard
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

Then, open the app-routing.module.ts file and define the routes for both modules. It will act as the main routing module in our application. After define routes, the app-routing.module.ts file is as follows.

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [
  {
    //whe app starting, it will navigate to login page
    path:'', loadChildren: './login/login.module#LoginModule'
  },
  {
    path:'dashboard', loadChildren: './dashboard/dashboard.module#DashboardModule'
    
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

Run the application again. As you can see, our route guard is not working yet. But, our routes are working properly.

So, this is the time to activate our route guard. I activate route guard for the dashboard. Therefore, a user who does not have a token, can’t visit the dashboard. After activating the route guard, the app-routing.module.ts file is as follows.

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

//import our guard
import { AuthGuard } from './guards/auth.guard';

const routes: Routes = [
  {
    //whe app starting, it will navigate to login page
    path:'', loadChildren: './login/login.module#LoginModule'
  },
  {
    path:'dashboard', loadChildren: './dashboard/dashboard.module#DashboardModule', 
    canActivate:[AuthGuard]
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

Finally, to demonstrate the execution of the route guard, I create a log-out button on the dashboard. When the user clicking on the logout button, the access token is removed from the local storage and the user is navigated to the login page. So, after creating the logout button, the dashboard.component.html and the dashboard.component.ts files as follows.

<p>
  dashboard works!
</p>

<button (click)=logoutUser()>Logout</button>
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';

@Component({
  selector: 'app-dashboard',
  templateUrl: './dashboard.component.html',
  styleUrls: ['./dashboard.component.scss']
})
export class DashboardComponent implements OnInit {

  constructor(private router : Router) { }

  ngOnInit() {
  }

  logoutUser(){

  	//remove token, when user logout
  	localStorage.removeItem('token');

  	//this navigate the user into login page
  	this.router.navigate(['']);
  }
}

Now, we have done. When a user tries to navigate to the dashboard without an access token, the user is automatically redirected to login page.

logout button for angular router guard tutorial

If you have any question please comment in the comment section and if you like this tutorial please don’t forget to share. Please like our facebook page.

Thanks for reading.

Please follow and like us:
Summary
How to create a router guard in Angular
Article Name
How to create a router guard in Angular
Description
In this tutorial, i will show you how to create a router guard in Angular 5. Protecting routes using router guards is a common thing in web application development. As a wonderful framework, Angular provides a very easiest way to create routes guards for your Angular project.
Author
Publisher Name
Angular + Laravel
Publisher Logo