A Practical Guide to Implementing Two-Factor Authentication

Two-factor authentication (2FA) adds a critical layer of security beyond passwords. By requiring a second factor—something the user has (like a phone) or is (biometrics)—you dramatically reduce account takeover risks. This tutorial walks through a straightforward implementation using Time-based One-Time Passwords (TOTP), the most common 2FA method.

Before coding, decide which 2FA method fits your app. TOTP (e.g., Google Authenticator) is free and offline-capable. SMS codes are easier but less secure. WebAuthn (hardware keys or biometrics) offers the strongest protection. For this guide, we will focus on TOTP because it balances security and user experience.

Article illustration

1. Generate and Store a Secret Key

When a user enables 2FA, generate a unique random secret key per account. Use a library like otplib (Node.js) or pyotp (Python). Store the key securely in your database – encrypted at rest is best. Never expose the plain secret except during initial setup via a QR code.

// Example with otplib (Node.js)
const secret = otplib.authenticator.generateSecret();
// Save secret to user record

2. Present a QR Code for Easy Setup

Display the secret as a QR code so the user can scan it with any authenticator app. Use a library like qrcode to encode the standard otpauth:// URI. Include the issuer name (your app) and the user’s email. This makes scanning seamless.

  • Format: otpauth://totp/{issuer}:{email}?secret={secret}&issuer={issuer}
  • Test scanning with Google Authenticator, Authy, or Microsoft Authenticator.

3. Verify the First Code

Before enabling 2FA, ask the user to enter the code from their authenticator app. Validate it using the same library with the stored secret. This proves they have scanned the QR correctly and prevents lockouts.

const isValid = otplib.authenticator.check(token, secret);
if (isValid) { /* enable 2FA */ }

4. Handle Login and Backup Codes

During login, prompt for the TOTP code after password verification. Also generate a set of single-use backup codes (e.g., 8 codes of 8 digits). Store them as hashed values. Give these to the user to safekeep for account recovery.

  • Rate-limit TOTP attempts to prevent brute force.
  • Provide a “remember this device” option (trust token) for convenience.

Conclusion

Implementing TOTP-based 2FA requires only a few steps: secret generation, QR display, code verification, and backup codes. Use well-tested libraries, secure your secrets, and always test the full flow. Your users will thank you for the extra security.

sarah antaboga
Author: sarah antaboga

Leave a Reply

Your email address will not be published. Required fields are marked *