Skip to main content
Implementing Two-Factor Authentication with TOTP

Implementing Two-Factor Authentication with TOTP

Andrius LukminasAndrius LukminasJanuary 21, 20267 min read97 views

Security First

Two-factor authentication is no longer optional for any serious platform. We implemented TOTP (Time-based One-Time Password) with backup codes as our primary 2FA method.

Architecture Overview

Our 2FA system consists of several components:

  • Setup Flow - QR code generation and secret storage
  • Verification Flow - TOTP validation during login
  • Backup Codes - Emergency access with single-use codes
  • OAuth Integration - 2FA requirement for OAuth logins too

The Pending Session Pattern

When a user with 2FA enabled logs in, we create a "pending" session stored in verification_tokens:

// Create pending 2FA session
const pendingSessionId = uuid();
await prisma.verification_tokens.create({
  data: {
    identifier: `2fa_pending:${pendingSessionId}`,
    token: user.id,
    expires: new Date(Date.now() + 5 * 60 * 1000),
  },
});

This session expires in 5 minutes, giving users time to complete verification without security risks.

Backup Codes

We generate 10 backup codes during 2FA setup, each hashed with Argon2id. When used, a code is marked as consumed to prevent reuse.

Related Articles

Comments

0/5000 characters

Comments from guests require moderation.