Angular Authentication using JWT token

Posted on March 28, 2023
angularjwt seriesauthenticationAngular authenticationJWT authenticationJSON Web TokenToken-based authenticationAngular JWT authenticationAuthentication interceptors in AngularToken storage

Angular Authentication using JWT token

Read the JWT token Authentication in ASP.Net Core article located here, since the remainder of this article will focus on writing implementing JWT authentication in angular.

Outcome of Implementation

Local Storage - Access token

Local Storage - Access token

Bearer token in Authentication Header Bearer token

Steps to implementing JWT authentication in angular

  1. Install dependencies
  2. Create a login page (Here is article to support JWT in backend JWT token Authentication in ASP.Net Core)
  3. Create AuthService
  4. Store JWT token
  5. Create guard to prevent route
  6. Create Http Interceptor

Here is Github profile to see raw code.

  1. Download the sample example here to play.
  2. Run the sample angular application in npm run start
  3. Run the backend webapi to generate jwt token
  4. login with email/password and notice Network and local storage from developer tool. Following are snapshots to follow.

Here is basic diagram of JWT authentication in angular

diagram of JWT authentication

Let's understand the steps and code to follow

Install the required dependencies

Install the @auth0/angular-jwt libraries using npm.

npm install @auth0/angular-jwt --save

Create a login page

Create a new component, login.component.ts, to handle user login. This component will call the auth.service to authenticate the user and receive a JWT token.

login.component.html

<div class="container">
  <h1>Login</h1>
  <form>
    <label for="username"><b>Email</b></label>
    <input type="text" placeholder="Enter Email" name="username" value="codehack.witharun@gmail.com" required>

    <label for="password"><b>Password</b></label>
    <input type="password" placeholder="Enter Password" value="CodeHack_with_arun" name="password" required>

    <button type="button" (click)="login()">Login</button>
  </form>
</div>

login.component.ts

import { Component } from '@angular/core';
import { Router } from '@angular/router';
import { AuthService } from 'src/app/auth.service';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})
export class LoginComponent {
  constructor(
    private router: Router,
    private authService: AuthService) { }

  login() {
    //This is just for demo but you should not do like this.
    let loginData = { email: 'codehack.witharun@gmail.com', password: 'CodeHack_with_arun' }
    this.authService.authenticateUser(loginData)
      .subscribe(result => {
        localStorage.setItem("access_token", JSON.stringify(result?.token));
        this.router.navigate(['/']);
      });
  }
}

Login Screen

Create AuthService

Create a new service, auth.service.ts, to manage authentication. This service will handle the creation and storage of JWT tokens.

Enable CORS in Webapi, if your frontend and backend deployed in different host

import { HttpClient } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { JwtHelperService } from "@auth0/angular-jwt";
import { Observable } from "rxjs";

@Injectable({
  providedIn: 'root'
})
export class AuthService {
  basePath = "http://localhost:5258/Auth/"
  constructor(private jwtHelper: JwtHelperService, private http: HttpClient) { }

  authenticateUser(loginData: any): Observable<any> {
    return this.http.post<any>(this.basePath, loginData)
  }

  getToken() {
    const token = localStorage.getItem('access_token');
    return token;
  }

  public isAuthenticated(): boolean {
    const token = localStorage.getItem('access_token');
    return !this.jwtHelper.isTokenExpired(token);
  }
}

Create guard to prevent route

Create guards to protect routes that require authentication. These guards will check if the user has a valid JWT token before allowing access to the route.

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

@Injectable({
  providedIn: 'root'
})
export class AuthGuard implements CanActivate {

  constructor(private authService: AuthService, private router: Router) { }

  canActivate() {
    if (this.authService.isAuthenticated()) {
      return true;
    } else {
      this.router.navigate(['/login']);
      return false;
    }
  }

}

Enable the guard on route

Enable the guard on route

Create Http Interceptor

Create an HTTP interceptor to include the JWT token in every HTTP request. This interceptor will add the token to the Authorization header.

import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler } from '@angular/common/http';
import { AuthService } from './auth.service';

@Injectable({
  providedIn: 'root'
})
export class AuthInterceptor implements HttpInterceptor {

  constructor(private authService: AuthService) { }

  intercept(req: HttpRequest<any>, next: HttpHandler) {
    const authToken = this.authService.getToken();
    const authReq = req.clone({
      headers: req.headers.set('Authorization', 'Bearer ' + authToken)
    });
    return next.handle(authReq);
  }

}

Make sure to register HTTP Interceptor in app.module

HTTP Interceptor

Summary

Implementing JWT authentication in an Angular application involves installing the required dependencies, creating an authentication service to handle login, logout, and authentication checks, creating a login component to handle the login form, creating an auth guard to protect routes that require authentication, and adding the auth guard to the routing configuration. The @auth0/angular-jwt library is used to work with JWT tokens

Thanks for reading!


Posted on March 28, 2023
Profile Picture

Arun Yadav

Software Architect | Full Stack Web Developer | Cloud/Containers

Subscribe
to our Newsletter

Signup for our weekly newsletter to get the latest news, articles and update in your inbox.