Blog#222: 🔐Two-Factor Authentication (2FA) in Node.js Express

222

Hi, I'm Tuan, a Full-stack Web Developer from Tokyo 😊. Follow my blog to not miss out on useful and interesting articles in the future.

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 });
  res.send(secret);
});

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);
  
  res.send(`
    <div>
      <h2>Scan the QR Code with a TOTP App</h2>
      <img src="${qrCodeUrl}" alt="QR Code">
      <p><strong>Secret:</strong> ${secret.base32}</p>
    </div>
  `);
});

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');
app.use(bodyParser.json());

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.

Conclusion

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.

And Finally

As always, I hope you enjoyed this article and got something new. Thank you and see you in the next articles!

If you liked this article, please give me a like and subscribe to support me. Thank you. 😊

NGUYỄN ANH TUẤN

Xin chào, mình là Tuấn, một kỹ sư phần mềm đang làm việc tại Tokyo. Đây là blog cá nhân nơi mình chia sẻ kiến thức và kinh nghiệm trong quá trình phát triển bản thân. Hy vọng blog sẽ là nguồn cảm hứng và động lực cho các bạn. Hãy cùng mình học hỏi và trưởng thành mỗi ngày nhé!

Đăng nhận xét

Mới hơn Cũ hơn