How to create a router guard in Angular

How to create a router guard in Angular

angular tutorials

angular tutorials

Hello,

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, see this.

let’s start.

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

So, 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 runs our new angular application in browser. If your installation was success, you can see running application without errors.

Okay, now we have to create login module, dashboard module, auth guard and auth service.

Notice: login module and 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 dashboard, you can execute corresponding code snippet in profile module.

To create above things run following commands consecutively.

  1. ng generate module login double dash routing.

2. ng generate component login.

3. ng generate module dashboard double dash routing.

4. ng generate component dashboard.

5. ng generate guard guards / auth.

6. ng generate service services / auth.

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

<router-outlet></router-outlet>

Then, open login.component.html file and create login form. Here I’m creating login button in login form. Add some styles to that form. After doing those thing 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 login button, the token will be saved in local storage and user will be navigated to dashboard. In this tutorials I use “my_token “as access token. In your case it may be JWT token, OAuth token etc.

Then, set router path in login-routing.module.ts file. 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 dashboard-routing.module.ts file and set router path. 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

Okay, this is the time to setup router guard. So, open auth.service.ts file and create a rxjs behavior subject instance with default value, false. Then, define hasToken() method to check whether, current user has a token or not. Also, create setLoggedIn() method to update logged-in status of logged-in-$ stream.  After doing those things, 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 logged-in-$ stream. Also, define loggen-in-status property with 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 app.module.ts file and import auth guard and 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 app-routing.module.ts file and define routes for both modules. it will act as main routing module in our application. After define routes, 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 application again. As you can see, our route guard is not working until now. But, our rotes are working properly.

So, this is the time to activate our route guard. I activate route guard for dashboard. Therefore, an user who does not have token, can’t visit dashboard. After activating the route guard, 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 our route guard, i create log-out button in dashboard. When user clicking on logout button, the access token is removed from local storage and user is navigated to log in page. So, after creating logout button dashboard.component.html and 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(['']);
  }
}

Okay, now we have done. When user try to navigate to dashboard without a access token, 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.

Thanks for reading.

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
Please follow and like us: