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. 😊