Image by Robinraj Premchand from Pixabay

2FA with Node.js and Google Authenticator

Allistair Vilakazi

--

Identity theft has always been a problem in society. With the proliferation of the internet and the devices connected to it, our digital identities have never had to fend the vast amount of tech-savvy identity thieves out there. Identity theft has become one of the most prevalent forms of cyber-crimes.

With so many of these cyber-crimes happening every day on the internet, its become a requirement for all developers to implement two-factor authentication (2FA) whenever data has to be protected. For more information on 2FA, see the end of the article.

Most people use two-factor authentication almost every day through the use of ATMs. An ATM often requires a bank card (1st authentication method — something you know) and a PIN (2nd authentication method — something you have). Both authentication methods are used to verify the person trying to access the bank account. That’s basically the concept of two-factor authentication in a nutshell.

If you are a Node developer who takes data security seriously, as all developers should, then this article will be of significant value to you. If you aren’t a Node developer then this article will still offer great value because the concepts discussed can be transferred across most other programming languages and frameworks. Today, we will be using Google Authenticator, but there are many more authenticator applications — Microsoft Authenticator or Twilio Authy— in the wild.

Overview

This article will go in detail on the process, with examples, of implementing two-factor authentication with Node and Google Authenticator. It’s important to note that this project uses Typescript. I am a strong believer in type safety and moving more errors to compile time.

The article also serves as documentation for my implementation, as I will be learning along.

You can find the source code for a simple implementation at this Github repository.

The repository is a simplified version of Marcin Wanago’s repository on this topic, amongst others.

Implementing 2FA with Node and Google Authenticator

The code is already implemented with the 1st authentication method — user login with credentials. This one would fall under the digital identity, which is something you know.

In this case, we will be using cookie-based authentication. For those who are interested in an overview on authentication and the differences between cookie-based authentication and token-based authentication, please do read the following article.

We will be implementing the 2nd authentication method — user verification code with an authenticator app. And this under the physical identity, which is something you have.

With two-factor authentication we need to verify a user through the use of 2 authentication methods. We will use a few packages to achieve two-factor authentication, namely:

  • speakeasy — for creating secrets
  • qrcode — for QR codes used by Google Authenticator

Implementation steps:

  1. Generate a secret
  2. Create a QR code

1. Generate a secret

We need to generate a secret key that can uniquely identify a user of our application. This is where the speakeasy package comes in.

npm install speakeasy @types/speakeasy

The speakeasy package can generate secret codes for our application. The object returned when generating a secret with the package contains a base32 secret code for user validation and otpauth_url for generating QR codes and, more importantly, is compatible with Google Authenticator’s One Time Password Authentication (OTPA).

2. Create a QR code

We also need to provide a way for Google Authenticator to read our key and provide us with time-based verification codes. This is where the qrcode package comes in.

npm install qrcode @types/qrcode

We will generate QR codes on the server and return them to the user so that they can scan the code into Google Authenticator. Scanning is much faster than typing in a key into the Authenticator app and is quite the standard. I don’t recall any time in my life where I opted to use a key over a QR code.

User process

Registration:

  1. A user register’s with us, or you, and creates an authenticated, secure account using credentials. (The credentials are their digital identity. As an added layer of security, the user is automatically logged out after one hour and will need to login to get a valid token).
Register the user

Two-factor authentication setup:

  1. A user generates a QR code while authenticated. (The generated code can be scanned using any supported authenticator app, in our case — Google Authenticator, to receive a Time-based One-time Password, or TOTP).
Generate a QR code for the user
  1. A user turns on 2FA for the account with a TOTP. (The verification code, or TOTP, is used to verify whether or not the external secret matches the internal secret. If it matches, your device will become your physical identity, in addition to your digital identity).
Turn on 2FA for the user
  1. A user is required to login (1st authentication method — something you know) and provide a verification code (2nd authentication method — something you have).
Authenticate with 2FA for the user

Conclusion

With an ever-growing privacy concern in the world, two-factor authentication can be an important tool in ensuring that your users are safe and that their data is private.

Two-factor authentication is very easy to implement but can make a significant improvement to the security of your user’s data. Be a responsible developer and ensure that your users do not get easily compromised.

NOTE: My repository was inspired by Marcin Wanago’s repository with the original source code.

--

--