Auth Guard (JWT) in Angular

In the previous post I showed how to manage a token in an angular application. Now I show you how you can use the Auth Guard mechanism so that you can not go on specific components  without authentication on the SPA application side.

Example

At first let’s create auth guard service by use command ng g guard auth. After my modification it’s look like below.

import { AuthService } from './../_services/AuthService.service';
import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';

@Injectable({
  providedIn: 'root'
})

export class AuthGuard implements CanActivate {
  constructor(private authService: AuthService,
    private router: Router) { }
  canActivate(): boolean {
    if (this.authService.tokenExistAndNotExpire()) {
      console.log('You can be here.');
      return true;
    }
    this.router.navigate(['']);
    console.log('You can not be here!');
    return false;
  }
}

What I did was injected auth service which will validate the correctness of the token. And returns information about whether something can be activated or not and additionally displayed information in the console about whether someone can be here or not.

Next create two components (named “private” and “home) and call them using the buttons that put in the main view.

<div class="form-group d-flex justify-content-center align-items-center vertical-center">
  <a class="btn btn-primary" [routerLink]="['/private']" routerLinkActive="router-link-active">Private</a>
  <a class="btn btn-info" [routerLink]="['/home']" routerLinkActive="router-link-active">Home</a>
</div>
<router-outlet></router-outlet>

Let’s look at routing now.

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { PrivateComponent } from './Private/Private.component';
import { HomeComponent } from './Home/Home.component';

const routes: Routes = [
  { path: '', component: HomeComponent },
  { path: 'home', component: HomeComponent },
  { path: 'private', component: PrivateComponent },
  { path: '**', redirectTo: '', pathMatch: 'full' }
];

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

Looks normal (more about routing here) but add the case that only a person with a token can go to the private view.

To do that you can add a canActivate attribute to a specific routing with a reference to our auth guard and it looks like this.

  { path: 'private', component: PrivateComponent, canActivate: [AuthGuard] },

But if we have many such cases that we want to use canActivate and we want to follow the DRY rule then we can use such a code.

  {
    path: '',
    runGuardsAndResolvers: 'always',
    canActivate: [AuthGuard],
    children: [
      { path: 'private', component: PrivateComponent },
      { path: 'other', component: OtherComponent },
      ... etc.
    ]
  }

More about routes here.

Entire auth guard.

import { AuthService } from './../_services/AuthService.service';
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})

export class AuthGuard implements CanActivate {
  constructor(private authService: AuthService,
    private router: Router) { }
  canActivate(): boolean {
    if (this.authService.tokenExistAndNotExpire()) {
      console.log('You can be here.');
      return true;
    }
    this.router.navigate(['']);
    console.log('You can not be here!');
    return false;
  }
}

And it looks as follows.

Whole code on github.

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *