Authentication

How to make a scalable OTP service using NodeJs

OTP microservice

Divyansh Agarwal
May 31 · 9 min read
Photo by NeONBRAND on Unsplash

About OTP

Problem in conventional OTP services:

Solution

Let’s Begin

├───.env
├───.gitignore
├───app.js
├───package-lock.json
├───package.json
├───sequelize.js
├───middlewares
│ └───crypt.js
├───models
│ └───OTP.js
├───routes
│ ├───sendOTP_to_email.js
│ ├───sendOTP_to_phone.js
│ └───verifyOTP.js
└───templates
├───email
│ ├───forget.js
│ └───verification.js
└───sms
├───forget.js
└───verification.js

Install the following dependencies

npm i express cors dotenv morgan sequelize sequelize-cli pg helmet otp-generator nodemailer crypto aws-sdk nodemon

package.json

package.json

App.js

Models

OTP Model

Sequelize Connection file

Sequelize Connection File
dialectOptions: {
"ssl": {
"require": true,
"rejectUnauthorized": false
}
}
Environment File for setting Database

Routes

Send OTP to Email Route

Send OTP to email Route
const otp = otpGenerator.generate(6, { alphabets: false, upperCase: false, specialChars: false });

const now = new Date();
const expiration_time = AddMinutesToTime(now,10);

const otp_instance = await OTP.create({
otp: otp,
expiration_time: expiration_time
});
var details={ 
"timestamp": now,
"check": email,
"success": true,
"message":"OTP sent to user",
"otp_id": otp_instance.id
}
const encoded= await encode(JSON.stringify(details))
if(type){    
if(type=="VERIFICATION"){
const {message, subject_mail} = require('../Templates/Email/verification');
email_message=message(otp)
email_subject=subject_mail
}
else if(type=="FORGET"){
const {message, subject_mail} = require('../Templates/Email/forget');
email_message=message(otp)
email_subject=subject_mail
}
else{
const response={"Status":"Failure","Details":"Incorrect Type Provided"}
return res.status(400).send(response)
}
}
Environment Settings for Nodemailer

Send OTP to Phone Route

Send OTP to phone number Route
Environment Settings for AWS SNS

Templates

Email Templates

Email Template for Reset Password
Email Template for Email Verification
Email Template for 2FA

SMS Templates

SMS Template for Reset Password
SMS Template for Phone Number Verification
SMS Template for Login

Verify Route

OTP Verification Route
try{    
decoded = await decode(verification_key)
}
catch(err) {
const response={"Status":"Failure", "Details":"Bad Request"}
return res.status(400).send(response)
}
var obj= JSON.parse(decoded)  
const check_obj = obj.check
if(check_obj!=check){
const response={"Status":"Failure", "Details": "OTP was not sent to this particular email or phone number"}
return res.status(400).send(response)
}
if(otp_instance!=null){    
if(otp_instance.verified!=true){
if (dates.compare(otp_instance.expiration_time, currentdate)==1{
if(otp===otp_instance.otp){
otp_instance.verified=true
otp_instance.save()
const response={"Status":"Success", "Details":"OTP Matched", "Check": check}
return res.status(200).send(response)
}
else{
const response={"Status":"Failure","Details":"OTP NOT Matched"}
return res.status(400).send(response)
}
}
else{
const response={"Status":"Failure","Details":"OTP Expired"}
return res.status(400).send(response)
}
}
else{
const response={"Status":"Failure","Details":"OTP Already Used"}
return res.status(400).send(response)
}
}
else{
const response={"Status":"Failure","Details":"Bad Request"}
return res.status(400).send(response)
}

Middleware

Encryption and Decryption Middleware

Encryption and Decryption Middleware
async function encode(string) {    
var key = password_derive_bytes(password, '', 100, 32);
var cipher = crypto.createCipheriv('aes-256-cbc', key, ivstring);
var part1 = cipher.update(string, 'utf8');
var part2 = cipher.final();
const encrypted = Buffer.concat([part1, part2]).toString('base64');
return encrypted;
}
async function decode(string) {    
var key = password_derive_bytes(password, '', 100, 32);
var decipher = crypto.createDecipheriv('aes-256-cbc', key, ivstring);
var decrypted = decipher.update(string, 'base64', 'utf8');
decrypted += decipher.final();
return decrypted;
}
Final Environment File

Try it yourself

OTP Verification Screen in 2FA Application

Links

Geek Culture

Proud to geek out. Follow to join our 1M monthly readers.