Multi-Factor Authentication — Complete MFA Implementation Guide
In this tutorial, you will learn about Multi. We cover key concepts, practical examples, and best practices to help you master this topic.
Multi-factor authentication (MFA) requires users to provide two or more verification factors: something you know (password), something you have (phone or hardware key), or something you are (biometric).
What You'll Learn
You'll learn MFA strategies including TOTP, SMS codes, and hardware security keys, and how to implement them in your API.
Why It Matters
MFA blocks 99.9% of automated attacks according to Microsoft. It is required by Compliance standards (PCI DSS, SOC 2, HIPAA) and increasingly mandated by insurance providers.
Real-World Use
A cryptocurrency exchange requires MFA for all withdrawals. The user enters their password and then a time-based code from their authenticator app. Even if the password is phished, the attacker cannot complete the withdrawal without the second factor.
sequenceDiagram
participant User
participant API
User->>API: POST /login (password)
API->>User: 200 (MFA required, challenge)
User->>API: POST /mfa/challenge (TOTP code)
API->>API: Verify TOTP
API->>User: access_token
Implementation
import pyotp
import qrcode
from flask import Flask, request, jsonify
app = Flask(__name__)
users = {}
@app.route("/api/mfa/setup")
def setup_mfa():
user_id = get_current_user()
secret = pyotp.random_base32()
users[user_id]["totp_secret"] = secret
totp = pyotp.TOTP(secret)
provisioning_uri = totp.provisioning_uri(name=f"user-{user_id}", issuer_name="MyAPI")
return jsonify({"secret": secret, "provisioning_uri": provisioning_uri})
@app.route("/api/mfa/verify", methods=["POST"])
def verify_mfa():
user_id = get_current_user()
code = request.json.get("code")
secret = users[user_id].get("totp_secret")
totp = pyotp.TOTP(secret)
if totp.verify(code, valid_window=1):
users[user_id]["mfa_enabled"] = True
return jsonify({"message": "MFA enabled"})
return jsonify({"error": "Invalid code"}), 400
@app.route("/api/login", methods=["POST"])
def login():
if user["mfa_enabled"]:
code = request.json.get("mfa_code")
if not code or not totp.verify(code):
return jsonify({"error": "MFA required"}), 401
return jsonify({"token": create_token()})
Common Mistakes
| Mistake | Fix | |---------|-----| | SMS as only MFA method | SMS is vulnerable to SIM swapping; offer TOTP or hardware keys | | No backup codes | Users locked out if they lose their phone | Generate and show backup codes during setup | | MFA fatigue | Attackers spam push notifications | Require number matching or location-based MFA | | Not Rate Limiting MFA attempts | Brute-force TOTP codes | Rate limit MFA verification attempts | | Skipping MFA on API-only clients | APIs need MFA too | Support MFA tokens in Authorization header |
Practice Questions
- What are the three types of authentication factors?
- How does TOTP work?
- Why is SMS MFA considered less secure?
- What are backup codes?
- How do hardware security keys (FIDO2/WebAuthn) work?
Challenge
Implement TOTP-based MFA for a login API. Include: MFA enrollment, QR Code Generation, code verification, backup codes, and rate limiting on MFA attempts.
What's Next
Learn about passwordless authentication for a frictionless user experience.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro