JWT authentication with NestJS

A Backend JWT Application
Summary
- What is NestJS?
- What is JWT?
- Starting the NestJS Backend
- NestJS Modules & Components
- Bcrypt Password
- REST Client for VSCode
- JWT Token
- Passport NodeJS Authentication
- 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


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 🏸

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





