Two-Factor Authentication (2FA) Implementation Guide
Two-factor authentication adds a second layer of security beyond username and password. It requires two different types of authentication factors: knowledge (password), possession (phone, security key), and inherence (fingerprint, face).
Why 2FA Matters
Over 80% of data breaches involve stolen credentials. 2FA blocks 100% of automated bots, 96% of bulk phishing, and 76% of targeted attacks.
1. Implementation Options
TOTP (Time-based One-Time Password)
Most widely used. Users scan a QR code with an authenticator app (Google Authenticator, Authy). Codes change every 30 seconds.
Pros: No network needed, standardized (RFC 6238), low cost
Cons: Users need authenticator app, backup recovery needs design
SMS Codes
Simplest but weakest. NIST no longer recommends SMS as primary 2FA.
Push Notifications
Best UX (one-tap approval), shows login context.
Hardware Security Keys (FIDO2/WebAuthn)
Most secure option (YubiKey, Google Titan). Resistant to phishing.
Biometrics
Fingerprint, face ID. Convenient but biometric data cannot be changed if leaked.
2. Implementation Steps
Setup Flow
- User goes to security settings
- Selects 2FA method (TOTP recommended)
- QR code displayed for scanning
- User inputs one-time code to confirm
- Recovery codes provided
Recovery Codes
Generate 10 one-time recovery codes. Store hashed (bcrypt/SHA-256) on server. Display only once.
import secrets
def generate_recovery_codes(count=10):
codes = []
for _ in range(count):
code = secrets.token_hex(4).upper()
codes.append(f"{code[:4]}-{code[4:]}")
return codes
3. Security Considerations
- TOTP seeds: Encrypt at rest, audit access
- SIM swap: Prefer TOTP/push over SMS
- Brute force: Limit attempts (5 attempts = 5-min lockout)
- Clock drift: Allow ±1 time window
4. Summary
Use TOTP as default (balance security and UX), SMS as fallback, hardware keys for high-security users. Key design: good recovery flow, trusted device options, reasonable verification limits.