Skip to content

A Crash Course to Two-Factor Authentication

Posted on:April 18, 2023 at 03:22 PM

A Crash Course to Two-Factor Authentication

Two-Factor Authentication (2FA) is a security feature that adds an extra layer of protection to your online accounts by requiring two separate authentication methods to verify your identity.

How 2FA Works

Two-factor authentication works on the principle of using two of the three main authentication factors:

In order to successfully authenticate, the user must provide two of the three factors. For example, if you’re logging into a website with 2FA enabled, you may be prompted to enter your password as well as a code that is sent to your mobile phone via SMS or generated by an authentication app.

TOTP Explained

TOTP is a Time-based One-Time Password algorithm that generates a unique code every few seconds. The code is generated using a secret key and the current time. The secret key is stored on the user’s mobile phone or hardware token, and the code is sent to the user’s mobile phone via SMS or generated by an authentication app. Simple enough, right?

Why 2FA is Important

Two-factor authentication is important because it adds an extra layer of security to your online accounts. If your password is compromised, an attacker will still need access to your mobile phone or hardware token in order to access your account. This makes it much harder for an attacker to gain access to your account.

Javascript Implementation

We will need to do some initial setup before we can implement 2FA in our Node.js application. We’re going to use the Google Authentication Strategy. This strategy uses the TOTP algorithm to generate a unique code every 30 seconds. We will input this code into an input field on our login form. If the code is valid, we will be redirected to the home page. If the code is invalid, we will be redirected to the login page.

Step 1: Create a Google Account (Optional)

We’ll need have or create a google account.

Step 2: Install Google Authenticator (Optional)

Install the Google Authenticator mobile app. Android and iOS.

This app will generate the TOTP codes that we will use to verify the user’s identity.

Step 3: Install Passport Dependencies

In an existing Node.js project we’ll need to install Passport Dependencies

npm install passport-2fa-totp

Step 4: Configure Passport.

Create a new file called passport.js in the root directory of your Node.js application. Then, add the following code to the file:

var GoogleAuthenticator = require('passport-2fa-totp').GoogeAuthenticator;
var TwoFAStartegy = require('passport-2fa-totp').Strategy;

...

passport.use(new TwoFAStartegy(function (username, password, done) {
    // 1st step verification: username and password

    User.findOne({ username: username }, function (err, user) {
        if (err) { return done(err); }
        if (!user) { return done(null, false); }
        if (!user.verifyPassword(password)) { return done(null, false); }
        return done(null, user);
    });
}, function (user, done) {
    // 2nd step verification: TOTP code from Google Authenticator

    if (!user.secret) {
        done(new Error("Google Authenticator is not setup yet."));
    } else {
        // Google Authenticator uses 30 seconds key period
        // https://github.com/google/google-authenticator/wiki/Key-Uri-Format

        var secret = GoogleAuthenticator.decodeSecret(user.secret);
        done(null, secret, 30);
    }
}));

Step 5: Configure Routes.

We will need to route the user to the login form and the home page. We will also need to route the user to the login form if the login fails. Add the following code to the app.js file or the file where you configure your routes:

// This route will render the login form
app.get("/login", function (req, res) {
  res.render("login");
});

// This route will render the home page
app.get("/", function (req, res) {
  res.render("home");
});

// This route will render the login form
app.post(
  "/login",
  passport.authenticate("2fa-totp", { failureRedirect: "/login" }),
  function (req, res) {
    res.redirect("/");
  }
);

Step 6: Configure Views

We can then create a component that will render the login form. The framework you are using will strongly influence the way you implement this component. The following code is an example of how you might implement a login form using HTML elements:

<form action="/login" method="post">
  <div>
    <label>Username:</label>
    <input type="text" name="username" />
  </div>
  <div>
    <label>Password:</label>
    <input type="password" name="password" />
  </div>
  <div>
    <label>Google Authenticator Code:</label>
    <input type="text" name="code" />
  </div>
  <div>
    <input type="submit" value="Log In" />
  </div>
</form>

Step 7: Configure User Model

We will need to add a secret field to our user model. This field will store the user’s secret key. We will also need to add a verifyPassword method to our user model. This method will verify the user’s password. Add the following code to your user model:

var mongoose = require("mongoose"); // MongoDB ODM
var Schema = mongoose.Schema; // Schema constructor
var bcrypt = require("bcrypt"); // Password hashing library

var UserSchema = new Schema({
  // User schema definition
  username: { type: String, required: true, unique: true },
  password: { type: String, required: true },
  secret: { type: String },
});

// Hash the user's password before saving it to the database
UserSchema.methods.verifyPassword = function (password) {
  return bcrypt.compareSync(password, this.password);
};

module.exports = mongoose.model("User", UserSchema);

Outro

Two-factor authentication is a security measure that requires two different methods of authentication to access a system. Security doesn’t have to be complicated. In fact, it can be as simple as using a mobile app to generate a unique code every few seconds. We can use this code to verify the user’s identity. This is a simple and effective way to add an extra layer of security to your online accounts.

If you’re interested in learning more about security, check out my article on The Evolution of Passwords and Password Vaults.