Node.js › Authentication & Authorization

What is Multi-Factor Authentication (MFA), and how would you implement Time-based One-Time Password (TOTP) support in a Node.js app?

Advanced

Answer

MFA requires a user to prove their identity via two or more independent factors (something they know, like a password; something they have, like a phone; something they are, like a fingerprint) -- TOTP is a common 'something you have' factor that generates a six-digit code changing every 30 seconds, derived from a shared secret and the current time, verifiable without any network round-trip since both the server and an authenticator app (like Google Authenticator) compute the same code independently from the same secret and clock.
const speakeasy = require('speakeasy');

// Generating a secret during MFA setup
const secret = speakeasy.generateSecret({ name: 'MyApp' });
await User.update(userId, { totpSecret: secret.base32 });

// Verifying a code at login
const isValid = speakeasy.totp.verify({
  secret: user.totpSecret,
  encoding: 'base32',
  token: req.body.code,
  window: 1, // allows for slight clock drift
});
Real-world example A financial application requires users to enable TOTP-based MFA before accessing sensitive account settings, storing each user's TOTP secret encrypted at rest and verifying submitted six-digit codes with a small time-drift window to account for minor clock differences between the server and the user's phone.

Common follow-ups: How should the TOTP secret itself be protected in the database, given it's effectively as sensitive as a password?;What backup mechanism should be provided for users who lose access to their authenticator device?