Two-step Authentication using NodeJS and Termii
Tags: javascript, node, tutorial, otps
Published: 2022-05-14 17:22:34




![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7donpf08aebt7jwhtgks.jpg)

Most technology applications we use today integrate two-step authentication to improve security and prevent unauthorized access to private data. In this article, I want to show you how to implement two-step authentication in your web applications using your regular authentication method and OTPs (one-time passwords).
I will be using NodeJs and Express in the small application we will build but I will not be using a database; also, I will not be building a frontend for this, we will test everything from Postman (or you can use any api test client of your choice), these are to enable us to go straight to the point and reduce redundancy.
For the OTP, we will be integrating with Termii and the Termii [Token API](https://developers.termii.com/token) to be specific. This is because we would obviously need a messaging solution to handle the sending and delivery of SMS and [Termii](https://termii.com/) is just perfect for its simplicity.

## **Prerequisites**
In order to successfully complete this guide, you need:

- basic understanding of NodeJs and Javascript (ES6).
- an existing Node.js project. You can generate a REST skeleton using [Express Generator](https://expressjs.com/en/starter/generator.html).
- [Node.js](https://nodejs.org/en/) installed on your machine
- Postman client installed on your machine.



## **Setting Up — Project**

use [express-generator](https://expressjs.com/en/starter/generator.html) to generate a skeleton app :

```js
npx express-generator --no-view --git otp-app
$ cd otp-app
$ npm install
```

1. Create a Services folder and a Controller folder in your project folder, this is a pattern I like to work with personally, you can use any other if you feel like it.
2. create a .env file in your project directory and run the following:

```js
npm i dotenv
```
also, open up **app.js** and add this in as early as possible:

```js
require('dotenv').config();
```
We will install a [NodeJS SDK](https://www.npmjs.com/package/termii-nodejs) for the Termii APIs, this will allow us to reduce 10 lines of code to maybe just 1 while integrating. Run the following in your terminal.

```js
npm i termii-nodejs
```
With these, we’re good to go, let’s move on to setting up and getting an API key from Termii.


## **Setting Up — Termii**

- 
Visit [termii.com](https://termii.com) and sign up. Once that is done, you can find your API key on your dashboard. Copy and transfer it to your env file. Your env should look like this:

```js
SENDER_ID=your_sender_id_here
API_KEY=your_API_key_here
```

- 
Let’s sort out the Sender ID bit now. A **Sender ID** is a name or number that identifies the sender of an SMS message. You cannot send SMS without registering one, the good news is, you can register one on [your dashboard](https://accounts.termii.com/#/sms/sender-id-management) and have it approved within 24 hours. I have registered one already named _“Octopii”_. If you, however, need to test before your sender ID is approved then use the [Sandbox](https://accounts.termii.com/#/sandbox/sms) feature accessible from your dashboard.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k0rono4lq6djmmr551rh.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/77vbjb31udny29ps1ljk.png)

- 
Once we’ve done all these, we’re ready to implement two-step authentication anywhere in our application.



## **Sending OTPs**

Let’s start by configuring the routes. I will only be using the `routes/index.js` file. modify this file to look like this:

```js
var express = require('express');
var router = express.Router();
const otp = require('../controllers/otpController');
router.post('/send-otp', otp.sendOtp);
router.post('/verify-otp', otp.verifyOtp);
router.get('/balance', otp.checkBalance);
module.exports = router;
```
Here I defined 3 routes, actually, we only need 2 (the signup endpoint that sends the OTP and the verification endpoint), the balance endpoint is just nice to have, yunno, so we can always check how much credit we have left in our wallet.

As you must have guessed, now that we imported `/controllers/otpController.js` , we do need to create it inside the controllers folder.

```js
const otpService = require('../services/otpService');
const sendOtp = async(req, res) => {
   const name = req.body.name
   const phoneNumber = req.body.phone
   const response = await otpService.sendOtp(name, phoneNumber);
   res.status(200).json(response);
}
const verifyOtp = async(req, res) => {
}
const checkBalance = async(req, res) => {
  
}
module.exports = {
   sendOtp,
   verifyOtp,
   checkBalance
}
```
Here, we only want to process the **name** and **phone number** of the new user, in a real application, you’d probably have many more fields but this is concise because these are the only fields we need for what we’re trying to achieve. We then call the `sendOtp` method in `otpService`, we’ll be creating that right now.

Create a file titled `otpService.js` in the services folder and put this in:

```js
const Termii = require("termii-nodejs").Termii;
const sender_id = process.env.SENDER_ID;
const api_key = process.env.API_KEY;
const termii = new Termii({
	api_key: api_key,
	sender_id: sender_id,
	pin_time: 5,
});
const sendOtp = (name, phoneNumber) => {
   const pinPlaceholder = '< 1234 >';
   const message = `Hello ${name}, your OTP is ${pinPlaceholder}. This pin will expire in 1 minute.`;
   try{
       const response = termii.sendToken(phoneNumber, pinPlaceholder, message);
       return response;
   }
   catch(err){
       throw err;
   }
}
```
A number of things are happening here, first, we call and initialize the `termii-nodejs SDK` using our sender_id and api_key in our env file. make sure to provide correct details or your requests will return “unauthorized”.

The Termii Token API has a number of required parameters to send an OTP like the type of pin which can be numeric or alphanumeric, length of the pin, pin time (I set it for 5 minutes in my example), etc; you can see a full list of them [here](https://developers.termii.com/send-token). The SDK however [can set the defaults](https://github.com/drchibs/termii-nodejs#advanced-usage) for us and we only need to set the pin placeholder and the actual message, then make a call to the SDK `sendToken` method.
If we run npm start and make a call to `localhost:3000/send-otp` with the appropriate payload we should get something similar to this:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gk4v4jivgxuu5ifk9ks8.png)

That’s a 200 OK HTTP status which means our OTP has just been sent! make sure to note the `pinId` in the response, you need it to verify this OTP, ideally, you should persist this in a database and retrieve it when you need to but I will be passing it in the request I make to the verify endpoint.

> You should receive the SMS on your phone now. If you don’t, there’s a chance that DND (Do-Not-Disturb) is activated on your phone number and this sender ID delivers only on Non-DND numbers. OTPs generally should only be sent on DND-enabled sender IDs since they’re so important however DND routes are a little more expensive. To get this activated on your sender ID, reach out to the customer success team at Termii, they’re very responsive.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/omaa5zas8be7xtxprowy.jpeg)




## **Verifying OTPs**

Everything being equal we’re almost there. Let’s add the following to the `otpController.js` file:

```js
const verifyOtp = async(req, res) => {
   const pin = req.body.pin;
   const pinId = req.body.pinId;
   const response = await otpService.verifyOtp(pinId, pin);
   res.status(200).json(response);
}
```
Let’s also modify the `otpService.js` file again and add:

```js
const verifyOtp = (pindId, pin) => {
   try{
       const response = termii.verifyToken(pindId, pin);
       return response;
   }
   catch(err){
       throw err;
   }
 
}
```

If we call `http://localhost:3000/verify-otp` then we should have a working 2-step authentication fully implemented now.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ab93chlpeahabqobwucu.png)

There you have it, we have successfully implemented two-step authentication into our web application.

To see the full working code, you can check out the [project repo on Github](https://github.com/drchibs/node-otp-app).



## **Where to go from here**

For starters, now that you’ve verified this user, you can then go on to save the user or carry out whatever else you need to do.

You can also delve into the Termii official documentation to see other solutions like voice tokens and how you can integrate them with your application.