This document details the authentication flow, including Two-Factor Authentication (2FA).
1. The Flow Chart
2. Step-by-Step Logic
Step 1: Initial Login
- Endpoint:
POST /auth/login - Body:
email,password. - Logic:
- Verify password hash.
- Check
user.is_two_factor_enabled. - If False: Issue Access/Refresh Tokens immediately.
- If True (2FA Enabled):
- Method A: OTP (Email/Phone)
- Generate 6-digit OTP.
- Send to user.
- Method B: Authenticator App (TOTP)
- Do nothing (User already has the code generator).
- Return JSON:
{ "mfa_required": true, "temp_token": "...", "method": "totp" }. temp_token: Short-lived (5m) JWT. Scope:mfa_verify.
- Method A: OTP (Email/Phone)
Step 2: MFA Verification
- Endpoint:
POST /auth/mfa/verify - Headers:
Authorization: Bearer <temp_token> - Body:
code("123456"). - Logic:
- Verify
temp_token. - If Method = TOTP:
- Fetch
user.two_factor_secret(Decrypted). - Verify
codeusing TOTP algorithm (Window: +/- 1 step).
- Fetch
- If Method = OTP:
- Check
verificationstable foridentifier=user.emailandcode.
- Check
- If valid:
- If valid:
- Delete OTP (prevent replay).
- Issue Real Tokens (Access/Refresh).
- Verify
3. Email Verification (Registration)
Similar flow, but happens before user creation (as defined in Registration Workflow).
POST /auth/send-otp(Email) -> Received 6-digit code.POST /auth/verify-otp(Code) -> Receiveverification_token.POST /register(Data +verification_token).
4. Enabling TOTP (Authenticator App)
User wants to switch from Email OTP to Google Authenticator.
- Frontend:
POST /auth/mfa/setup(Auth required). - API:
- Generate random
secret(Base32). - Return
secretandotpauth://URL (for QR Code).
- Generate random
- Frontend: Shows QR Code. User scans it.
- Frontend:
POST /auth/mfa/enable(Body:{ code: "..." }). - API:
- Verify code against the pending secret.
- Commit: Update
userstable ->two_factor_secret = secret,two_factor_method = totp.
4. Edge Cases
- Lost Device: User needs recovery codes (Future Feature).
- OTP Delay: Code valid for 10 minutes.
- Brute Force:
verificationstable tracksattempts. > 3 fails -> Invalidate code.