Skip to main content

Command Palette

Search for a command to run...

JWT authentication with NestJS

Published
6 min readView as Markdown
JWT authentication with NestJS

A Backend JWT Application

Summary

  1. What is NestJS?
  2. What is JWT?
  3. Starting the NestJS Backend
  4. NestJS Modules & Components
  5. Bcrypt Password
  6. REST Client for VSCode
  7. JWT Token
  8. Passport NodeJS Authentication
  9. References

1. What is NestJS?

  • NestJS is a Node Framework 🆓
  • Since 2017 🆕
  • CoC — Convention Over Configuration 🧾
  • TypeScript´👨‍💻
  • Scalable Architecture 🧗‍♀️
  • Integration with multiple databases 💿
  • MicroService Support 🚀
  • API REST 📲

Value offer

The NestJS Value Proposition is to use an MVC architecture in an agile way

NestJS Language

Uses TypeScript as a development language, Jest with Test Tools, and AngularJS concepts

NestJS with Postgres Database

The NestJS Value Proposition is to use an MVC architecture in an agile way

TypeORM with Nest JS Application API development – @tkssharma | Tarun  Sharma | My Profile

2. What is JWT?

  • JSON Web Token
  • API REST-based on HTTP Stateless requisition
  • Uses a Token and not a Cookie

Use Cases with Cookie Auth

  • Only Web Browser Application

Use Cases with Token Auth

  • Mobile
  • Desktop
  • CLI
  • IoT

Cookie Auth vs Token Auth

3. Starting the NestJS Backend

node --version

npm install -g @nestjs/cli

nest new authentication-with-NestJS

¨npm run start:dev

4. Concepts of NestJS?

a) NestJS Modules & Components

  • Module A to Feature 1
  • Module B to Feature 2

Clean Architecture

b) Clean Architecture

  • Use Case ===> Feature
  • Repository Interfaces
  • Domain Services
  • Domain Model

c) Generate an NestJS Module

nest g module auth

// Output

/src/auth/auth.module.ts

after auth module

after auth module

c) Generate an NestJS Controller

/ // root
/auth // auth module
/auth/login // controler login

nest g controller auth/login

login controller

  • login.controller.spec.ts

import { Test, TestingModule } from '@nestjs/testing';

import { LoginController } from './login.controller';

describe('LoginController', () => {

let controller: LoginController;

beforeEach(async () => {

const module: TestingModule = await Test.createTestingModule({

controllers: [LoginController],

}).compile();

controller = module.get(LoginController);

});

it('should be defined', () => {

expect(controller).toBeDefined();

});

});

  • login.controller.ts

import { Controller } from '@nestjs/common';

@Controller('login')

export class LoginController {}

/ // root
/auth // auth module
/auth/login // controler login
/auth/auth // controler auth

// Generate Auth Controller
nest g controller auth/auth

// Generate Auth Service to Access Database
nest g service auth/auth

5. BCrypt Password

bcrypt is a [password-hashing function](https://en.wikipedia.org/wiki/Password-hashing_function "Password-hashing function") designed by [Niels Provos](https://en.wikipedia.org/wiki/NielsProvos "Niels Provos") and David Mazières, based on the [Blowfish](https://en.wikipedia.org/wiki/Blowfish%28cipher%29 "Blowfish (cipher)") cipher and presented at [USENIX](https://en.wikipedia.org/wiki/USENIX "USENIX") in 1999.[1] Besides incorporating a [salt](https://en.wikipedia.org/wiki/Salt_%28cryptography%29 "Salt (cryptography)") to protect against [rainbow table](https://en.wikipedia.org/wiki/Rainbow_table "Rainbow table") attacks, bcrypt is an adaptive function: over time, the iteration count can be increased to make it slower, so it remains resistant to [brute-force search](https://en.wikipedia.org/wiki/Brute-force_search "Brute-force search") attacks even with increasing computation power.

The bcrypt function is the default password [hash algorithm](https://en.wikipedia.org/wiki/Hash_algorithm "Hash algorithm") for [OpenBSD](https://en.wikipedia.org/wiki/OpenBSD "OpenBSD")[2] and was the default for some [Linux distributions](https://en.wikipedia.org/wiki/Linux_distribution "Linux distribution") such as [SUSE Linux](https://en.wikipedia.org/wiki/SUSE_Linux "SUSE Linux").[3]

npm install bcrypt --save

generate-pass.js

const bcrypt = require('bcrypt');

const saltRounds = 10;

const password = process.argv.slice(2)[0];

bcrypt.genSalt( saltRounds,

function(err, salt){

bcrypt.hash(password, salt, function(err,hash){

console.log(hash)

})

});

Password Generate

node generate-pass.js 12345678910

❯ node generate-pass.js 12345678910
$2b$10$OLBu.sG9stD6j3PpeO6sw.QuZmxk4RUnfMVTJ.8afMLdj/9HwsRGC

6. REST Client for VS CODE

[REST Client - Visual Studio Marketplace
Extension for Visual Studio Code - REST Client for Visual Studio Codemarketplace.visualstudio.com](https://marketplace.visualstudio.com/items?itemName=humao.rest-client "https://marketplace.visualstudio.com/items?itemName=humao.rest-client")

REST Client

GET https://example.com/comments/1 HTTP/1.1  

###  

GET https://example.com/topics/1 HTTP/1.1  

###  

POST https://example.com/comments HTTP/1.1  
content-type: application/json  

{  
    "name": "sample",  
    "time": "Wed, 21 Oct 2015 18:27:50 GMT"  
}

POST Method

GET Method

7. JWT Token

  • JWT — JSON Web Token
  • Header
  • Payload
  • Signature
  • AutoContent

JWT = (1) Header + (2) Payload + (3) Signature

1) Header

2) Payload

  • jwt.ts

const header: {alg: string, typ: string; } = {

alg: 'HS256',

typ: 'JWT',

};

const payload: {username: string; name:string; exp:number;} = {

username: 'user1@user.com',

name: 'Luiz Carlos',

exp: new Date().getTime(), //timestamp

};

const key: "abcd123456" = 'abcd123456';

// header + payload + key

// base64

const headerEncoded = Buffer

.from( JSON.stringify(header))

.toString("base64");

const payloadEncoded = Buffer

.from( JSON.stringify(payload))

.toString("base64");

console.log("1.0) Header -----------------------------------");

console.log("1.1) header > ", header);

console.log("1.2) headerEncoded > ", headerEncoded);

console.log("2.0) Payload -----------------------------------");

console.log("2.1) payload > ", payload);

console.log("2.2) payloadEncoded > ", payloadEncoded);

node_modules/.bin/ts-node jwt.ts

3) Signature

const key: "abcd123456" = 'abcd123456';

const crypt = require('crypto');

const signature = crypt.createHmac('sha256',key)

.update(`${headerEncoded}.${payloadEncoded}`)

.digest("bin");

console.log("3.0) Signature -----------------------------------");

console.log("3.1) signature > ", signature);

Header + Payload + Signature = JWT

Install Library base64-URL

npm install base64-url --save

Implementation base64Url(signature)

const base64Url = require('base64url');

console.log("Token JWT - JSON Web Token Created");

console.log("JWT = [Header] + [Payload] + [Signature]");

console.log("JWT [Token] >",

`${headerEncoded}.${payloadEncoded}.${base64Url(signature)}`

);

Token JWT = [header] + [Payload] + [Signature]

Token JWT

JWT [Token] > eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InVzZXIxQHVzZXIuY29tIiwibmFtZSI6Ikx1aXogQ2FybG9zIiwiZXhwIjoxNjQxNzk4ODA5MjM2fQ==.WS6MhFktJki4cZSZu56mu1rFVUG7ANJfZfJhTfXpWwo

Validation Token JWT

[JWT.IO
JSON Web Token (JWT) is a compact URL-safe means of representing claims to be transferred between two parties. The…jwt.io](http://jwt.io/ "http://jwt.io/")

JWT with Bug 🏸

https://jwt.io/#debugger-io?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InVzZXIxQHVzZXIuY29tIiwibmFtZSI6Ikx1aXogQ2FybG9zIiwiZXhwIjoxNjQxNzk4ODA5MjM2fQ%3D%3D.WS6MhFktJki4cZSZu56mu1rFVUG7ANJfZfJhTfXpWwo

Validation JWT Token

JWT Correct !!!🚀

  • Token

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InVzZXIxQHVzZXIuY29tIiwibmFtZSI6Ikx1aXogQ2FybG9zIiwiZXhwIjoxNjQxNzk5NTkzMDc4fQ==.m9DFawDnG07PErE1PN8v0YMDN2xBFX2b6Xv8qOf_7mw

  • Secret

const key: "abcd123456" = 'abcd123456';

Validation JWT Ok

[JWT.IO
JSON Web Token (JWT) is a compact URL-safe means of representing claims to be transferred between two parties. The…jwt.io](https://jwt.io/#debugger-io?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InVzZXIxQHVzZXIuY29tIiwibmFtZSI6Ikx1aXogQ2FybG9zIiwiZXhwIjoxNjQxNzk5NTkzMDc4fQ.g9xdj639qgQgjuJ7MtTZokqNJaePsp11g3Rmtlp-Sz8 "https://jwt.io/#debugger-io?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InVzZXIxQHVzZXIuY29tIiwibmFtZSI6Ikx1aXogQ2FybG9zIiwiZXhwIjoxNjQxNzk5NTkzMDc4fQ.g9xdj639qgQgjuJ7MtTZokqNJaePsp11g3Rmtlp-Sz8")

Othe Example

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InVzZXIxQHVzZXIuY29tIiwibmFtZSI6Ikx1aXogQ2FybG9zIiwiZXhwIjoxNjQxODAxMDg3NTkxfQ.wF9iAYt9vqhHHgutq8bEWPO7HPDwAAP5Np3gj_VfjG8

[JWT.IO
JSON Web Token (JWT) is a compact URL-safe means of representing claims to be transferred between two parties. The…jwt.io](https://jwt.io/#debugger-io?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InVzZXIxQHVzZXIuY29tIiwibmFtZSI6Ikx1aXogQ2FybG9zIiwiZXhwIjoxNjQxODAxMDg3NTkxfQ.wF9iAYt9vqhHHgutq8bEWPO7HPDwAAP5Np3gj_VfjG8 "https://jwt.io/#debugger-io?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InVzZXIxQHVzZXIuY29tIiwibmFtZSI6Ikx1aXogQ2FybG9zIiwiZXhwIjoxNjQxODAxMDg3NTkxfQ.wF9iAYt9vqhHHgutq8bEWPO7HPDwAAP5Np3gj_VfjG8")

8. Passport NodeJS Authentication

Simple, unobtrusive authentication for Node.js

app.js — vim

passport.authenticate(‘facebook’);(‘google’);(‘apple’);(‘microsoft’);(‘twitter’);(‘linkedin’);(‘github’);(‘openid’);

Passport is authentication middleware for Node.js. Extremely flexible and modular, Passport can be unobtrusively dropped in to any Express-based web application. A comprehensive set of strategies support authentication using a username and password, Facebook, Twitter, and more.

[Passport.js
Passport is authentication middleware for Node.js. Extremely flexible and modular, Passport can be unobtrusively…www.passportjs.org](https://www.passportjs.org/ "https://www.passportjs.org/")

npm install passport --save

npm install passport-jwt --save

npm install @types/passport --save-dev

npm install @types/passport-jwt --save-dev

npm install [@nestjs/jwt](http://twitter.com/nestjs/jwt "Twitter profile for @nestjs/jwt")

NestJS Generate Auth Strategy

nest g service auth/jwt-strategy

npm install @nestjs/passport --save

Test Application

npm run start:dev

Test API

/api/post.api.htpp

Running API Test

Our JWT Token

"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOjEsInVzZXJuYW1lIjoidXNlcjFAdXNlci5jb20iLCJpYXQiOjE2NDE4NDQyNDUsImV4cCI6MTY0MTg0NDMwNX0.1mH-PD-s8712sILMCMBQX0_KlDX0df3jNneo_bIhb00"

[JWT.IO
JSON Web Token (JWT) is a compact URL-safe means of representing claims to be transferred between two parties. The…jwt.io](https://jwt.io/#debugger-io?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOjEsInVzZXJuYW1lIjoidXNlcjFAdXNlci5jb20iLCJpYXQiOjE2NDE4NDQ0NTYsImV4cCI6MTY0MTg0NDUxNn0.3ctGMelKiC3MJVsWb0ow8WcNuW52e8gCZXXjL9KmCK4 "https://jwt.io/#debugger-io?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOjEsInVzZXJuYW1lIjoidXNlcjFAdXNlci5jb20iLCJpYXQiOjE2NDE4NDQ0NTYsImV4cCI6MTY0MTg0NDUxNn0.3ctGMelKiC3MJVsWb0ow8WcNuW52e8gCZXXjL9KmCK4")

Access control with Token Authenticated

  • Guardian Tokens Access Authenticated

@UseGuards(JwtGuard)

  • authController.ts

import { Body, Controller, Get, Post, UseGuards } from '@nestjs/common';

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

import { JwtGuard } from './jwt.guard';

@Controller()

export class AuthController {

constructor(private authService: AuthService){}

@Post('login')

login(@Body() body ): {token:string} {

return { token: this.authService.login(body.username, body.password)}

}

// Criação Guardiao

@UseGuards(JwtGuard) // <<<<< Guardian Token

@Get('autenticado')

test(){

return {

name: "Pedro Alvares Cabral"

}

}

}

No Authorization Token

Authorization Token

References