Two Factor Authentication Using NodeJS

Posted By : Hotam Singh | 24-Mar-2018

Today I have come up with new article. How to use 2FA into our nodejs application. We will be using speakeasy module of NodeJS. So let's get started.

 

What is speakeasy?

 

Speakeasy is an OTP generator, which is ideal for use in 2FA(Two Factor Authentication). Speakeasy supports Google Authenticator and other 2F devices.

It provides robust support for custom token lengths. It is used for hashing algorithms and it is suitable for authentication windows  like SHA256 and SHA512. It also includes helpers such as generating a secret key as google authenticator does.

Speakeasy implements OTP(One Time Password) generators as it is standardized by the OATH.

 

Installation

 

 

Example:

 

Create a file app.js and paste below code.

//Include speakeasy into your node file.
var express = require('express')
var speakeasy = require("speakeasy");
var QRCode = require('qrcode');

var app = express();

app.get('/', function (req, res) {
    //Generate a secret key First.
    var secret = speakeasy.generateSecret({ length: 30 });

    console.log('secret.base32 : ' + secret.base32);

    //using speakeasy generate one time token.
    var token = speakeasy.totp({
        secret: secret.base32,
        encoding: 'base32',
    });

    console.log('token : ' + token);

    
    QRCode.toDataURL(secret.otpauth_url, function (err, data_url) {
        //console.log(data_url);

        // Display this data URL to the user in an <img> tag 
        // Example: 
        res.end('<!DOCTYPE html>\
        <html lang="en">\
        <head>\
            <meta charset="UTF-8">\
            <meta name="viewport" content="width=device-width, initial-scale=1.0">\
            <meta http-equiv="X-UA-Compatible" content="ie=edge">\
            <title>2FA example</title>\
        </head>\
        <body>\
            <img src="'+data_url+'" alt="Mountain View">\
            <div class="col-lg-2 col-sm-3 col-xs-6"> OTP : '+token+' </div>\
        </body>\
        </html>');
    });
});

//Verify OTP
app.post('/verify', function(req, res) {
	var token = req.body.token; // for testing I am just sending token to front-end. send this token with /verify POST request
	// Verify a given token 
	var tokenValidates = speakeasy.totp.verify({
		secret: secret.base32,
		encoding: 'base32',
		token: token,  //token is what created in get('/') request
		window: 6
	});
	return tokenValidates;
	// Returns true if the token matches 
});

app.listen(8082);
console.log('server running on port 8082');

Save this file and run using $ node app.js and visit http://localhost:8082 and you will see a QR code and OTP generated by speakeasy.

 

Usage:

 

If we want to enable 2FA(two factor authentication), and you want like how Google Authenticator. We need to follow below steps:

  1. Generate a secret
  2. Display a QR code to the user to scan or model popup to enter OTP. 
  3. Verify the token.

Note: We are focusing on OTP based 2FA. Even I had added code to display QR code that can also be scanned but I am not using QR code for the demo(code written above i.e app.js).

Now without wasting time, move forward to explain above three steps one by one.

 

Generate a secret: 

 

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
//Generate a secret key First.
 var secret = speakeasy.generateSecret({ length: 30 });

console.log('secret.base32 : ' + secret.base32);

//using speakeasy generate one time token.
var token = speakeasy.totp({
    secret: secret.base32,
    encoding: 'base32',
});

See app.js above for full code.

 

Display QR code and OTP to user:

 

 
// Display this data URL to the user in an <img> tag 
// Example: 
res.end('<!DOCTYPE html>\
    <html lang="en">\
        <head>\
            <meta charset="UTF-8">\
            <meta name="viewport" content="width=device-width, initial-scale=1.0">\
            <meta http-equiv="X-UA-Compatible" content="ie=edge">\
            <title>2FA example</title>\
        </head>\
        <body>\
            <img src="'+data_url+'" alt="Mountain View">\
            <div class="col-lg-2 col-sm-3 col-xs-6"> OTP : '+token+' </div>\
        </body>\
</html>');

See app.js above for full code.

 

Verify OTP:

 

 
//Verify OTP
app.post('/verify', function(req, res) {
	var token = req.body.token; // for testing I am just sending token to front-end. send this token with /verify POST request
	// Verify a given token 
	var tokenValidates = speakeasy.totp.verify({
		secret: secret.base32,
		encoding: 'base32',
		token: token,  //token is what created in get('/') request
		window: 6
	});
	return tokenValidates;
	// Returns true if the token matches 
});

 

Next: 

 

What we can do is, we can send OTP to a mobile number and verify that OTP through application. I have not implemented this functionality in this code session. You can do it your own. Select any message service provider and use their API to send message to mobile and verify.

Happy coding.

About Author

Author Image
Hotam Singh

Hotam has 1.5 years of experience in Node.JS. He has worked on Front End, JavaScript, Jquery, Backbone.JS, Database: MySQL, MongoDB. His hobbies are playing Sudoku/Puzzles and watching movies.

Request for Proposal

Name is required

Comment is required

Sending message..