Overview
Multi-Factor Authentication (MFA) adds an additional layer of security by requiring users to provide a second form of authentication beyond their password. SuperTokens Core implements Time-based One-Time Password (TOTP) for MFA, compatible with authenticator apps like Google Authenticator, Authy, and Microsoft Authenticator.TOTP Implementation
TOTP is implemented inio.supertokens.totp.Totp - View source
Standard: RFC 6238 (TOTP: Time-Based One-Time Password Algorithm)
Algorithm: HMAC-SHA1 with 6-digit codes
Device Registration
Users can register multiple TOTP devices (e.g., multiple phones, backup devices).Register Device
Create a new TOTP device for a user. Implementation:io.supertokens.totp.Totp.registerDevice() - View source
Process:
- Generate a random 160-bit secret key
- Base32 encode the secret
- Create device record (unverified)
- Return secret for QR code generation
/recipe/totp/device
Request Body:
Secret Key Generation
Implementation:io.supertokens.totp.Totp.generateSecret() - View source
QR Code Format
TOTP URIs follow the Google Authenticator format:Device Verification
Devices must be verified before they can be used for authentication.Verify Device
Verify a device by validating a TOTP code. Implementation:io.supertokens.totp.Totp.verifyDevice() - View source
Process:
- Check if device exists and is unverified
- Validate TOTP code against device secret
- Check rate limiting
- Mark device as verified
- Return verification status
/recipe/totp/device/verify
Request Body:
TOTP Verification
Verify TOTP codes during login or sensitive operations.Verify Code
Implementation:io.supertokens.totp.Totp.verifyCode() - View source
Validation Process:
- Retrieve all verified devices for user
- Check each device with time skew
- Prevent code replay attacks
- Enforce rate limiting
- Store used code with expiry
/recipe/totp/verify
Request Body:
Code Verification Algorithm
Implementation:io.supertokens.totp.Totp.checkCode() - View source
- Default: ±1 period (30 seconds before/after)
- Allows for clock drift between client and server
- Configurable per device
Rate Limiting
Protect against brute force attacks with sophisticated rate limiting. Implementation:io.supertokens.totp.Totp.checkAndStoreCode() - View source
Algorithm:
- Fetch all recent code attempts (valid and invalid)
- Count consecutive invalid attempts
- If max attempts reached, calculate cooldown time
- Block further attempts until cooldown expires
Replay Attack Prevention
Prevent the same code from being used multiple times. Implementation:- Store each used code with expiry time
- Check if code was previously used
- Reject code if still valid and previously used
- Expiry time = device.period × (2 × device.skew + 1)
- Period: 30 seconds
- Skew: 1
- Expiry: 30 × (2 × 1 + 1) = 90 seconds
Device Management
List Devices
Retrieve all TOTP devices for a user. Implementation:io.supertokens.totp.Totp.getDevices() - View source
API Endpoint:
GET /recipe/totp/device/list?userId={userId}
Response:
Remove Device
Delete a TOTP device. Implementation:io.supertokens.totp.Totp.removeDevice() - View source
API Endpoint:
POST /recipe/totp/device/remove
Request Body:
- Delete specified device
- If last device, delete user from TOTP system
- Return success
Update Device Name
Rename a TOTP device. Implementation:io.supertokens.totp.Totp.updateDeviceName() - View source
API Endpoint:
PUT /recipe/totp/device
Request Body:
Bulk Device Status
Check TOTP status for multiple users in a single query. Implementation:io.supertokens.totp.Totp.getBulkDeviceStatus() - View source
API Endpoint:
POST /recipe/totp/device/status/bulk
Request Body:
true: User has at least one verified TOTP devicefalse: User has devices but none are verifiednull: User has no TOTP devices
Import Devices
Import TOTP devices from other systems. Implementation:io.supertokens.totp.Totp.createDevices() - View source
API Endpoint:
POST /recipe/totp/device/import
Request Body:
Configuration
TOTP Settings
Device Parameters
Period:- Default: 30 seconds
- Standard: 30 seconds (most compatible)
- Range: 1-300 seconds
- Default: 1 (±30 seconds)
- Recommended: 1-2
- Higher values = more tolerance, less security
- Fixed: 6 digits
- Standard for maximum compatibility
Security Considerations
Secret Storage
- Secrets are stored in plaintext in the database
- Protect database access with encryption at rest
- Consider application-level encryption for secrets
Clock Synchronization
- Server time must be accurate (use NTP)
- Skew parameter allows for minor drift
- Monitor server time drift
Backup Codes
- Not implemented in core TOTP module
- Implement at application layer
- Store hashed like passwords
Recovery
- Require email/SMS verification for MFA reset
- Log all MFA changes
- Notify users of MFA changes
Best Practices
- Require MFA for sensitive operations: Not just login
- Allow multiple devices: Users need backup devices
- Clear device names: Help users identify their devices
- Verify immediately: Prompt users to verify after registration
- Provide QR codes: Easier than manual entry
- Show recovery options: Before users lose access
- Rate limiting: Prevent brute force attacks
- Audit logs: Track MFA changes and usage
- User education: Explain MFA benefits and usage
- Test thoroughly: Especially time-sensitive code validation
Common Issues
Time Synchronization
Problem: Codes are always invalid Solution:- Check server time with NTP
- Increase skew parameter temporarily
- Verify client device time
Code Already Used
Problem: Valid code rejected as used Solution:- This is intentional (replay prevention)
- Wait 30 seconds for new code
- Increase period if users frequently retry
Rate Limiting
Problem: Users locked out after failed attempts Solution:- Provide clear error messages with retry time
- Implement MFA recovery flow
- Consider adjusting max attempts or cooldown
Multi-Tenancy
TOTP devices are tenant-specific:- Users in different tenants have separate devices
- Rate limiting is per-tenant
- Configuration can vary by tenant