Skip to main content

Part-1 Angular JWT(JSON Web Token) Authentication(Access Token Implementation)

In this article, we are going to understand the steps on JWT authentication implementation in Angular(Version11 used in this sample) application. Here our main focus is on authenticate users using the JWT access token.

What Is JSON Web Token?:

JSON Web Token is a digitally signed and secured token for user validation. The jwt is constructed with 3 informative parts:
  • Header
  • Payload
  • Signature

Create A Sample Angular Application:

Let's begin by creating a sample application in which we are going to implement JWT authentication.
Command To Install Angular CLI:
npm install -g @angular/cli
Command To Create Angular App:
ng new your_app_name
Command To Install Angular Material:
ng add @angular/material

Angular JWT Library:

JWT library to decrypt the user info within the JWT access token.
Command To Run Angular JWT Library:
npm install @auth0/angular-jwt

Integrate Login Module:

Let's create all login files like the below structure.
src/app/login/login-route.module.ts:
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 LoginRouteModules {}
src/app/login/login.module.ts:
import { NgModule } from "@angular/core";
import { LoginComponent } from './login.component';
import { LoginRouteModules } from './login-route.module';

@NgModule({
  declarations:[
   LoginComponent
  ],
  imports:[
   LoginRouteModules
  ]
})
export class LoginModule{}
  • (Line: 7) Imported 'LoginComponent' into the declaration array.
  • (Line: 10) Impored 'LoginRouteModules'.
Load our login module into our app routing module.
src/app/app-routing.module.ts:
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [{
  path:'',
  loadChildren:() => import('./login/login.module').then(_ => _.LoginModule)
}];

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

Create Login Form:

src/app/login/login.component.html:
<form class="my-form">
  <h3>Login Form</h3>
  <mat-form-field class="my-fields">
   <mat-label>User Name</mat-label>
   <input matInput [(ngModel)]="loginForm.username" name="username">
  </mat-form-field>
  <mat-form-field class="my-fields">
   <mat-label>Password</mat-label>
   <input matInput type="password"  [(ngModel)]="loginForm.password" name="password">
  </mat-form-field>
  <button mat-raised-button color="primary" (click)="userLogin()">Login</button>
</form>
  • Create a login form, here we used the form model binding to capture the data. The 'Login' button registered with 'userLogin' method for form submission.
src/app/login/login.component.ts:
import { Component, OnInit } from '@angular/core';
@Component({
  templateUrl: 'login.component.html',
  styleUrls: ['login.component.css'],
})
export class LoginComponent implements OnInit {
  loginForm = {
    username: '',
    password: '',
  };

  ngOnInit(): void {}

  userLogin() {
      console.log(JSON.stringify(this.loginForm))
  }
}
Import the angular mater modules like below in the 'LoginModule'.
src/app/login/login.module.ts:
import { NgModule } from "@angular/core";
import { LoginComponent } from './login.component';
import { LoginRouteModules } from './login-route.module';
import { MatInputModule } from '@angular/material/input';
import { MatFormFieldModule } from '@angular/material/form-field';
import {FormsModule} from '@angular/forms';
import {MatButtonModule} from '@angular/material/button';

@NgModule({
  declarations:[
   LoginComponent
  ],
  imports:[
   FormsModule,
   MatInputModule,
   MatFormFieldModule,
   MatButtonModule,
   LoginRouteModules
  ]
})
export class LoginModule{}
  • Imported modules into 'LoginModule' are 'FormsModule', 'MatInputModule', 'MatFormFieldModule', 'MatButtonModule'.

Mock JWT Access Token:

As a front end developer no need to spend more time onto work on JWT authentication API (using nodejs, .net, java server programs). So let's use a sample JWT token by mocking it in a constant variable in our application, latter we will make a dynamic API call for fetching the Jwt token at the end section of this article.
A sample jwt token:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6IlRlc3QiLCJzdWIiOjIsImlhdCI6MTYwNDMwOTc0OSwiZXhwIjoxNjA0MzA5ODA5fQ.jHez9kegJ7GT1AO5A2fQp6Dg9A6PBmeiDW1YPaCQoYs

Create AuthService:

Now let's create an AuthService file that contains logic about user login/logout API calls of our angular application.

Let's define AuthService with basic configurations as below.
src/app/services/auth.service.ts:
import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable, of } from 'rxjs';
import { map } from 'rxjs/operators';
import { JwtHelperService } from '@auth0/angular-jwt';

@Injectable()
export class AuthService {
  userInfo = new BehaviorSubject(null);
  jwtHelper = new JwtHelperService();
  constructor(){}
}
  • (Line: 8) The 'userInfo' variable to store the user info decoded from the JWT access token. It's a type defined as 'BehaviorSubject' that loads from the 'rxjs' library.
  • (Line: 9) The 'jwtHelper' variable defines 'JwtHelperService' type that loads from '@auth0/angular-jwt' library.
Now let's implement login logic into AuthService using mock JWT token(late steps we will change to API call).
src/app/services/auth.service.ts:
userLogin(login:any):Observable<boolean>{
  if(login &&
  login.username &&
  login.password){
   const sampleJWT = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6IlRlc3QiLCJzdWIiOjIsImlhdCI6MTYwNDMwOTc0OSwiZXhwIjoxNjA0MzA5ODA5fQ.jHez9kegJ7GT1AO5A2fQp6Dg9A6PBmeiDW1YPaCQoYs";

   return of(sampleJWT).pipe(
   map((token) => {
	if(!token){
		return false;
	}
	localStorage.setItem("access_token", token);
	const decodedUser = this.jwtHelper.decodeToken(token);
	this.userInfo.next(decodedUser);
return true; })); } return of(false); }
  • (Line: 1) The 'userLogin' method returns boolean of observable type.
  • (Line: 5) The JWT mock token assigned to a constant variable.
  • For the mock JWT token process, we used the 'of' operator to make observable type because when we change the logic to API code that needs to be rewrite will be very less.
  • (Line: 12) For a single-page application common approach to store, the token is in browser local storage.
  • (Line: 13) Decoding the user info from the JWT access token.
Since AuthService needs to be globally accessed by the application, we need to import it in AppModule.
src/app/app.module.ts:
import { AuthService } from './services/auth.service';
// code hidden for display purpose
@NgModule({
  providers: [AuthService]
})
export class AppModule {}
Now update the 'LoginComponent' to invoke the login logic in the AuthServcie file.
src/app/login/login.component.ts:
import { Component, OnInit } from '@angular/core';
import {AuthService} from '../services/auth.service';

@Component({
  templateUrl: 'login.component.html',
  styleUrls: ['login.component.css'],
})
export class LoginComponent implements OnInit {
  loginForm = {
   username: '',
   password: '',
  };
  constructor(private authService:AuthService){}
  ngOnInit(): void {}

  userLogin() {
   this.authService.userLogin(this.loginForm)
   .subscribe(
   (value) => {
    if(value){
     alert('success');
    }else{
     alert('failed');
    }
    },
   (error)=>{
	 alert('failed error');
    }
   );
  }
}
  • (Line: 13) Injected AuthService into the LoginComponent.
  • Invoked AuthService login logic into our component 'userLogin' method.

Integrate User Dashboard Module:

Now in our sample application after login, we will navigate the user to his dashboard. Let's create dashboard files in the following structure.
src/app/dashboard/dashboard.component.ts:
import { Component, OnInit } from '@angular/core';
import { AuthService } from '../services/auth.service';

@Component({
  templateUrl:'dashboard.component.html'
})
export class DashboardComponent implements OnInit{
  userName:string = ''
  constructor(private authService:AuthService){}
  ngOnInit(): void {
   this.authService.userInfo.subscribe(value => {
	if(value){
	 this.userName = value.username;
	}
   })
  }
}
  • (Line: 9) The 'AuthService' injected
  • (Line: 11) Subscribe to 'userInfo' is a behavior subject variable in AuthService which contains jwt token decoded userInfo. Assigning the username value to the component variable to display in the header of the dashboard page.
src/app/dashboard/dashboard.component.html:
<h3>Welcome {{userName}} !</h3>
src/app/dashboard/dashboard-routing.module.ts:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { DashboardComponent } from './dashboard.component';

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

@NgModule({
  imports:[RouterModule.forChild(routes)],
  exports:[RouterModule]
})
export class DashboardRoutingModule {}
src/app/dashboard/dashboard.module.ts:
import { NgModule } from '@angular/core';
import { DashboardRoutingModule } from './dashboard-routing.module';
import { DashboardComponent } from './dashboard.component';

@NgModule({
  imports:[
   DashboardRoutingModule
  ],
  declarations:[
   DashboardComponent
  ]
})
export class DashboardModule {}
  • Registered 'DashboardRoutingModule', 'DashboardComponent' in our 'DashboardModule'.
Now to load the dashboard module with the lazy load feature configure the dashboard module into AppRoutingModule as below.
src/app/app-routing.module.ts:(Update Routes Array)
const routes: Routes = [{
  path:'',
  loadChildren:() => import('./login/login.module').then(_ => _.LoginModule)
},{
  path:'dashboard',
  loadChildren:() => import('./dashboard/dashboard.module').then(_ => _.DashboardModule)
}];
The final step to using the router we have to navigate the user to the dashboard page on successful login.
src/app/login/login.component.ts:
import { Router } from '@angular/router';
constructor(private router:Router){}
  • Inject 'Router' instance into the 'LoginComponent'
src/app/login/login.component.ts:(login method)
this.authService.userLogin(this.loginForm)
.subscribe(
  (value) => {
  if(value){
   this.router.navigate(["/dashboard"]);
  }else{
   alert('failed');
  }
  },
  (error)=>{
   alert('failed error');
  }
)
  • (Line: 5) On successful login navigate the user to 'dashboard'.

Create A Route Guard:

Now we need to protect our routes using angular guards like users not logged in then show only login page and if the user logged in then we can show pages like the dashboard.

Before creating route guard, here we are going to implement 2 more steps like 
  • Redirect based URL to login URL in AppRouting Module, this will give more flexibility in route guards for navigating to the login page.
  • Another thing is like in the AuthService file constructor we need to load the user information fetching jwt token from the browser localStorage this makes when the app closes and reopens then route guards work without any issues.
src/app/app-routing.module.ts:(Update Routes Array)
const routes: Routes = [{
  path:'',
  redirectTo:'login',
  pathMatch: 'full'
},{
  path:'login',
  loadChildren:() => import('./login/login.module').then(_ => _.LoginModule),
  
},{
  path:'dashboard',
  loadChildren:() => import('./dashboard/dashboard.module').then(_ => _.DashboardModule)
}];
  • Here I'm redirecting my base URL to the 'login' URL. (Note: This not a mandatory step based on your application requires you may skip this redirection step)
src/app/services/auth.services.ts:
// code hidden for disply purpose
export class AuthService {
  constructor() {
    this.loadUserInfo();
  }
  loadUserInfo() {
  let userdata = this.userInfo.getValue();
  if (!userdata) {
   const access_token = localStorage.getItem('access_token');
   if (access_token) {
	userdata = this.jwtHelper.decodeToken(access_token);
	this.userInfo.next(userdata);
   }
  }
  }
}
  • Here loading the user information by fetching the 'access_token' from local storage and decrypting and assigning the user information to the 'userInfo' variable. This 'userInfo' variable will be used by the route guard to verify the user is login or not. Because if an application closes and reopens all variables will be empty if that the case route guard unable to read the user information which makes our application authentication process inconsistent. So it is a mandatory step to load the user information in the 'AuthService' constructor.
Now let's write our route protecting guard 'AuthGuard'.
src/app/guards/auth.guard.ts:
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, Router } from '@angular/router';
import { Observable } from 'rxjs';
import { AuthService } from '../services/auth.service';

@Injectable()
export class AuthGuard implements CanActivate{
  constructor(
   private authService:AuthService,
   private router:Router){}
  canActivate(
   route: ActivatedRouteSnapshot, 
   state: RouterStateSnapshot)
   : boolean 
   | UrlTree 
   | Observable<boolean 
   | UrlTree> 
   | Promise<boolean 
   | UrlTree> {
   let userData = this.authService.userInfo.getValue();
   if(userData && userData.sub){ // sub represents user id value
	if(state.url.indexOf("/login") != -1){
	 // loggin user trying to access login page
	 this.router.navigate(["/dashboard"]);
	 return false;
	}
	else{
	 return true;
	}
   }else{
	if(state.url.indexOf("/login") == -1){
	 // not logged in users only navigate to login page
	 this.router.navigate(["/login"]);
	 return false;
	}
	else{
	 return true;
	}
   }    
  }
}
  • (Line: 6) The guards are also providers, so to make them consume by other entities they need to be decorated with an 'Injectable' decorator.
  • (Line: 9-10) Injected 'AtuhService' and 'Router' instance.
  • (Line: 11) The 'canActivate' is a guard method which gets automatically executed on the invocation of guard by the application routes.
  • (Line: 20) Fetching user information from the 'userInfo' variable in the AuthService.
  • So now if a user is logged in then the user can access any page other than the login page and suppose if not logged in then always redirect to the login page.
Now update the routes to use our AuthGuard to protect our routes.
src/app/app-routing.modulet.ts:(Update Route Array)
const routes: Routes = [{
  path:'',
  redirectTo:'login',
  pathMatch: 'full'
},{
  path:'login',
  loadChildren:() => import('./login/login.module').then(_ => _.LoginModule),
  canActivate: [AuthGuard]
},{
  path:'dashboard',
  loadChildren:() => import('./dashboard/dashboard.module').then(_ => _.DashboardModule),
  canActivate:[AuthGuard]
}];
Now register our AuthGuard in AppModule providers array.
src/app/app.module.ts:
import { AuthGuard } from './guards/auth.guard';
// code hidden for display purpose
@NgModule({
  providers: [AuthGuard]
})
export class AppModule {}
Now you can test by access the routes with and without login to check guard protection.

NestJS(Nodejs) Server JWT API:

Command To Install NestJS CLI:
npm i -g @nestjs/cli
Next, go to the root folder of the repo and run the command to install all the package
Command To Install ALL Packages In our Repository application:
npm install
That's all we have set up a JWT API in our local system for testing, now run the following command to start the application.
Command To Start NestJS APP:
npm run start:dev
Our jwt token endpoint
Url:- http://localhost:3000/auth/login
Payload:-
{
	"username":"test",
	"password":"1234"
}

note:- payload should be same as above, variable name 'username' and 'password'
don't change them, they are even case sensitive. credentials also use as above

Integrate JWT NetsJS API Endpoint:

Till now we have used a mocked JWT access token now in this section we are going to replace that with a real API endpoint(Nestjs endpoint).

Now let's register angular HttpClientModule in the AppModule.
src/app/app.module.ts:
import {HttpClientModule} from '@angular/common/http';
// code hidden for display purpose
@NgModule({
  imports: [HttpClientModule]
})
export class AppModule {}
Now load and inject the HttpClient instance into the AuthService.
src/app/services/auth.service.ts:
import { HttpClient } from '@angular/common/http';
// code hidden for display purpose
@Injectable()
export class AuthService {
  constructor(private http:HttpClient) {
    this.loadUserInfo();
  }
}
The final step is to update 'userLogin' method to use the API endpoint for user login in the AuthService.
src/app/services/auth.service.ts:
userLogin(login: any): Observable<boolean> {
  if (login && login.username && login.password) {
  return this.http.post("http://localhost:3000/auth/login",login).pipe(
   map((data: any) => {
    if (!data) {
	 return false;
    }
    localStorage.setItem('access_token', data.access_token);
    const decodedUser = this.jwtHelper.decodeToken(data.access_token);
    this.userInfo.next(decodedUser);
    return true;
    })
  );
  }
  return of(false);
}
That's all about JWT authentication steps in an angular application. In the next article, we will explore the usage of the refresh token.

Support Me!
Buy Me A Coffee PayPal Me

Wrapping Up:

Hopefully, I think this article delivered some useful information on the JWT authentication in angular application. I love to have your feedback, suggestions, and better techniques in the comment section below.

Refer:

Follow Me:

Comments

Popular posts from this blog

Angular 14 Reactive Forms Example

In this article, we will explore the Angular(14) reactive forms with an example. Reactive Forms: Angular reactive forms support model-driven techniques to handle the form's input values. The reactive forms state is immutable, any form filed change creates a new state for the form. Reactive forms are built around observable streams, where form inputs and values are provided as streams of input values, which can be accessed synchronously. Some key notations that involve in reactive forms are like: FormControl - each input element in the form is 'FormControl'. The 'FormControl' tracks the value and validation status of form fields. FormGroup - Track the value and validate the state of the group of 'FormControl'. FormBuilder - Angular service which can be used to create the 'FormGroup' or FormControl instance quickly. Form Array - That can hold infinite form control, this helps to create dynamic forms. Create An Angular(14) Application: Let'

.NET 7 Web API CRUD Using Entity Framework Core

In this article, we are going to implement a sample .NET 7 Web API CRUD using the Entity Framework Core. Web API: Web API is a framework for building HTTP services that can be accessed from any client like browser, mobile devices, and desktop apps. In simple terminology API(Application Programming Interface) means an interface module that contains programming functions that can be requested via HTTP calls either to fetch or update data for their respective clients. Some of the Key Characteristics of API: Supports HTTP verbs like 'GET', 'POST', 'PUT', 'DELETE', etc. Supports default responses like 'XML' and 'JSON'. Also can define custom responses. Supports self-hosting or individual hosting, so that all different kinds of apps can consume it. Authentication and Authorization are easy to implement. The ideal platform to build the REST full services. Install The SQL Server And SQL Management Studio: Let's install the SQL server on our l

ReactJS(v18) JWT Authentication Using HTTP Only Cookie

In this article, we will implement the ReactJS application authentication using the HTTP-only cookie. HTTP Only Cookie: In a SPA(Single Page Application) Authentication JWT token either can be stored in browser 'LocalStorage' or in 'Cookie'. Storing the JWT token inside of the cookie then the cookie should be HTTP Only. The HTTP-ONly cookie nature is that it will be only accessible by the server application. Client apps like javascript-based apps can't access the HTTP-Only cookie. So if we use the authentication with HTTP-only JWT cookie then we no need to implement the custom logic like adding authorization header or storing token data, etc at our client application. Because once the user authenticated cookie will be automatically sent to the server by the browser on every API call. Authentication API: To authenticate our client application with JWT HTTP-only cookie, I developed a NetJS(which is a node) Mock API. Check the GitHub link and read the document on G

.NET6 Web API CRUD Operation With Entity Framework Core

In this article, we are going to do a small demo on AspNetCore 6 Web API CRUD operations. What Is Web API: Web API is a framework for building HTTP services that can be accessed from any client like browser, mobile devices, desktop apps. In simple terminology API(Application Programming Interface) means an interface module that contains a programming function that can be requested via HTTP calls to save or fetch the data for their respective clients. Some of the key characteristics of API: Supports HTTP verbs like 'GET', 'POST', 'PUT', 'DELETE', etc. Supports default responses like 'XML' and 'JSON'. Also can define custom responses. Supports self-hosting or individual hosting, so that all different kinds of apps can consume it. Authentication and Authorization are easy to implement. The ideal platform to build REST full services. Create A .NET6 Web API Application: Let's create a .Net6 Web API sample application to accomplish our

Angular 14 State Management CRUD Example With NgRx(14)

In this article, we are going to implement the Angular(14) state management CRUD example with NgRx(14) NgRx Store For State Management: In an angular application to share consistent data between multiple components, we use NgRx state management. Using NgRx state helps to avoid unwanted API calls, easy to maintain consistent data, etc. The main building blocks for the NgRx store are: Actions - NgRx actions represents event to trigger the reducers to save the data into the stores. Reducer - Reducer's pure function, which is used to create a new state on data change. Store - The store is the model or entity that holds the data. Selector - Selector to fetch the slices of data from the store to angular components. Effects - Effects deals with external network calls like API. The effect gets executed based the action performed Ngrx State Management flow: The angular component needs data for binding.  So angular component calls an action that is responsible for invoking the API call.  Aft

Angular 14 Crud Example

In this article, we will implement CRUD operation in the Angular 14 application. Angular: Angular is a framework that can be used to build a single-page application. Angular applications are built with components that make our code simple and clean. Angular components compose of 3 files like TypeScript File(*.ts), Html File(*.html), CSS File(*.cs) Components typescript file and HTML file support 2-way binding which means data flow is bi-directional Component typescript file listens for all HTML events from the HTML file. Create Angular(14) Application: Let's create an Angular(14) application to begin our sample. Make sure to install the Angular CLI tool into our local machine because it provides easy CLI commands to play with the angular application. Command To Install Angular CLI npm install -g @angular/cli Run the below command to create the angular application. Command To Create Angular Application ng new name_of_your_app Note: While creating the app, you will see a noti

Unit Testing Asp.NetCore Web API Using xUnit[.NET6]

In this article, we are going to write test cases to an Asp.NetCore Web API(.NET6) application using the xUnit. xUnit For .NET: The xUnit for .Net is a free, open-source, community-focused unit testing tool for .NET applications. By default .Net also provides a xUnit project template to implement test cases. Unit test cases build upon the 'AAA' formula that means 'Arrange', 'Act' and 'Assert' Arrange - Declaring variables, objects, instantiating mocks, etc. Act - Calling or invoking the method that needs to be tested. Assert - The assert ensures that code behaves as expected means yielding expected output. Create An API And Unit Test Projects: Let's create a .Net6 Web API and xUnit sample applications to accomplish our demo. We can use either Visual Studio 2022 or Visual Studio Code(using .NET CLI commands) to create any.Net6 application. For this demo, I'm using the 'Visual Studio Code'(using the .NET CLI command) editor. Create a fo

Part-1 Angular JWT Authentication Using HTTP Only Cookie[Angular V13]

In this article, we are going to implement a sample angular application authentication using HTTP only cookie that contains a JWT token. HTTP Only JWT Cookie: In a SPA(Single Page Application) Authentication JWT token either can be stored in browser 'LocalStorage' or in 'Cookie'. Storing JWT token inside of the cookie then the cookie should be HTTP Only. The HTTP-Only cookie nature is that it will be only accessible by the server application. Client apps like javascript-based apps can't access the HTTP-Only cookie. So if we use authentication with HTTP only JWT cookie then we no need to implement custom logic like adding authorization header or storing token data, etc at our client application. Because once the user authenticated cookie will be automatically sent to the server by the browser on every API call. Authentication API: To implement JWT cookie authentication we need to set up an API. For that, I had created a mock authentication API(Using the NestJS Se

ReactJS(v18) Authentication With JWT AccessToken And Refresh Token

In this article, we are going to do ReactJS(v18) application authentication using the JWT Access Token and Refresh Token. JSON Web Token(JWT): JSON Web Token is a digitally signed and secured token for user validation. The JWT is constructed with 3 important parts: Header Payload Signature Create ReactJS Application: Let's create a ReactJS application to accomplish our demo. npx create-react-app name-of-your-app Configure React Bootstrap Library: Let's install the React Bootstrap library npm install react-bootstrap bootstrap Now add the bootstrap CSS reference in 'index.js'. src/index.js: import 'bootstrap/dist/css/bootstrap.min.css' Create A React Component 'Layout': Let's add a React component like 'Layout' in 'components/shared' folders(new folders). src/components/shared/Layout.js: import Navbar from "react-bootstrap/Navbar"; import { Container } from "react-bootstrap"; import Nav from "react-boot

A Small Guide On NestJS Queues

NestJS Application Queues helps to deal with application scaling and performance challenges. When To Use Queues?: API request that mostly involves in time taking operations like CPU bound operation, doing them synchronously which will result in thread blocking. So to avoid these issues, it is an appropriate way to make the CPU-bound operation separate background job.  In nestjs one of the best solutions for these kinds of tasks is to implement the Queues. For queueing mechanism in the nestjs application most recommended library is '@nestjs/bull'(Bull is nodejs queue library). The 'Bull' depends on Redis cache for data storage like a job. So in this queueing technique, we will create services like 'Producer' and 'Consumer'. The 'Producer' is used to push our jobs into the Redis stores. The consumer will read those jobs(eg: CPU Bound Operations) and process them. So by using this queues technique user requests processed very fastly because actually