🔐Two-Factor Authentication (2FA) in Node.js Express

1. Introduction to Two-Factor Authentication (2FA)

1.1. What is Two-Factor Authentication (2FA)?

Two-Factor Authentication (2FA) is an extra layer of security added to the standard username and password-based authentication process. It requires users to provide two different types of evidence, or factors, to prove their identity during the authentication process. These factors typically include something the user knows (e.g., a password) and something the user has (e.g., a code sent to their phone). By combining these two factors, the chances of unauthorized access are significantly reduced.

1.2. Why Use Two-Factor Authentication?

Two-Factor Authentication adds an extra layer of protection to user accounts, making it harder for attackers to gain unauthorized access. It is particularly useful in situations where passwords may be compromised, as the additional factor can help prevent unauthorized access. Implementing 2FA in web applications can increase user trust and improve overall security.

2. Setting Up a Node.js Express Application

2.1. Prerequisites

To follow along with this tutorial, you should have:

  • Node.js and npm installed
  • A basic understanding of JavaScript and Node.js
  • Familiarity with the Express web framework

2.2. Creating a New Express Application

First, let's create a new Node.js Express application. In your terminal, run the following commands:

$ mkdir node-2fa
$ cd node-2fa
$ npm init -y
$ npm install express

Create an app.js file in the root directory and add the following code:

const express = require('express');
const app = express();

app.get('/', (req, res) => {
  res.send('Hello, Two-Factor Authentication!');

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);

Now, start the application by running the following command:

$ node app.js

Visit http://localhost:3000 in your browser to see the welcome message.

3. Implementing 2FA using Time-Based Onnee-Time Passwords (TOTP)

3.1. What is Time-Based Onnee-Time Password (TOTP)?

Time-Based Onnee-Time Password (TOTP) is an algorithm used to generate onnee-time passwords based on the current time. It is commonly used for Two-Factor Authentication in conjunction with a mobile app or other device that generates the TOTP codes. The TOTP algorithm is defined in the RFC 6238 standard.

3.2. Installing the Required Dependencies

We will use the speakeasy library to generate TOTP codes and the qrcode library to generate QR codes for easy setup of TOTP apps like Google Authenticator. Install these dependencies by running:

$ npm install speakeasy qrcode

3.3. Generating a TOTP Secret

First, let's create a route to generate a TOTP secret for a user. Update your app.js with the following code:

const speakeasy = require('speakeasy');

app.get('/generate-secret', (req, res) => {
  const secret = speakeasy.generateSecret({ length: 20 });

Now, you can visit http://localhost:3000/generate-secret to generate a new TOTP secret.

3.4. Creating a QR Code for the TOTP Secret

We will create a QR code that can be scanned with a TOTP app like Google Authenticator, which will then generate the correct codes based on the secret. Update your app.js with the following code:

const QRCode = require('qrcode');

app.get('/generate-qr', async (req, res) => {
  const secret = speakeasy.generateSecret({ length: 20 });
  const qrCodeUrl = await QRCode.toDataURL(secret.otpauth_url);
      <h2>Scan the QR Code with a TOTP App</h2>
      <img src="${qrCodeUrl}" alt="QR Code">
      <p><strong>Secret:</strong> ${secret.base32}</p>

Now, visit http://localhost:3000/generate-qr to see the generated QR code and the corresponding TOTP secret.

4. Verifying the TOTP Code

4.1. Installing Middleware for Parsing JSON

We will be receiving the TOTP code and secret from the client as JSON data. To parse the JSON data, we need to install and use the body-parser middleware. Install it by running:

$ npm install body-parser

Now, add the following code to app.js to use the middleware:

const bodyParser = require('body-parser');

4.2. Creating a Route to Verify the TOTP Code

Now let's create a route to verify the TOTP code submitted by the user. Update your app.js with the following code:

app.post('/verify-totp', (req, res) => {
  const { token, secret } = req.body;

  const verified = speakeasy.totp.verify({
    secret: secret,
    encoding: 'base32',
    token: token,

  if (verified) {
    res.send({ status: 'success', message: 'Two-Factor Authentication successful!' });
  } else {
    res.send({ status: 'error', message: 'Invalid token. Please try again.' });

This route receives the TOTP code and secret from the client, then uses the speakeasy.totp.verify method to check if the provided code is correct.

5. Testing the TOTP Verification

To test the TOTP verification, you can use a tool like Postman or Curl to send a POST request to the /verify-totp route with a JSON payload containing the token and secret. The token can be generated using a TOTP app like Google Authenticator, and the secret can be obtained from the /generate-qr route.

Heree's an example of how to test the route using Curl:

$ curl -X POST -H "Content-Type: application/json" -d '{"token": "123456", "secret": "your-secret-here"}' http://localhost:3000/verify-totp

Replace "123456" with the token generated by your TOTP app and "your-secret-here" with the secret obtained from the /generate-qr route.


In this tutorial, we've implemented Two-Factor Authentication (2FA) in a Node.js Express application using Time-Based Onnee-Time Passwords (TOTP). We used the speakeasy library to generate and verify TOTP codes and the qrcode library to create QR codes for easy setup with TOTP apps like Google Authenticator. By integrating 2FA into your application, you can significantly enhance security and protect user accounts from unauthorized access.

Moving forward, you can further improve this implementation by:

  • Integrating user registration and login functionality
  • Storing the TOTP secret securely for each user in a database
  • Adding recovery options, such as backup codes or email/SMS-based recovery, in case the user loses access to their TOTP app

By continuing to explore and enhance the security features of your application, you can ensure that you're providing the best possible user experience while keeping user data safe and secure.

Mình hy vọng bạn thích bài viết này và học thêm được điều gì đó mới.

Donate mình một ly cafe hoặc 1 cây bút bi để mình có thêm động lực cho ra nhiều bài viết hay và chất lượng hơn trong tương lai nhé. À mà nếu bạn có bất kỳ câu hỏi nào thì đừng ngại comment hoặc liên hệ mình qua: Zalo - 0374226770 hoặc Facebook. Mình xin cảm ơn.

Momo: NGUYỄN ANH TUẤN - 0374226770

TPBank: NGUYỄN ANH TUẤN - 0374226770 (hoặc 01681423001)


All Rights Reserved

Let's register a Viblo Account to get more interesting posts.