TOTP Plugin
A plugin for implementing TOTP-based two-factor authentication.
Overview
The TOTP plugin provides Time-based One-Time Password (TOTP) authentication and backup codes for implementing two-factor authentication (2FA) in your application. This plugin enables users to secure their accounts with authenticator apps like Google Authenticator, Microsoft Authenticator, or Authy, along with backup codes for account recovery.
Key Features
- TOTP Generation & Verification: Supports standard TOTP algorithm with configurable digit count and period
- Backup Codes: Automatically generate backup codes for account recovery
- Trusted Devices: Option to trust devices to skip TOTP verification on subsequent logins
- Event Hooks: Integration with the event bus for custom actions on TOTP events
- Configurable Settings: Customizable expiry times, cookie settings, and security options
Configuration
Standalone Mode
[totp]
enabled = true
skip_verification_on_enable = false # Skip password verification on enable
backup_code_count = 10 # Number of backup codes to generate (default: 10)
trusted_device_duration = "720h" # How long to trust a device (30 days default)
trusted_devices_auto_cleanup = true # Automatically clean up expired trusted devices (default: false)
trusted_devices_cleanup_interval = "1h" # Interval for cleaning up expired trusted devices (default: 1 hour)
pending_token_expiry = "5m" # Expiry time for pending token (default: 5 minutes)
secure_cookie = true # Use secure flag on cookies (set to true in production)
same_site = "lax" # SameSite cookie policy (lax, strict, none)Library Mode
import (
totpplugin "github.com/Authula/authula/plugins/totp"
totpplugintypes "github.com/Authula/authula/plugins/totp/types"
)
totpPlugin := totpplugin.New(totpplugintypes.TOTPPluginConfig{
Enabled: true,
SkipVerificationOnEnable: false,
BackupCodeCount: 10,
TrustedDeviceDuration: 30 * 24 * time.Hour,
TrustedDevicesAutoCleanup: true,
TrustedDevicesCleanupInterval: 1 * time.Hour,
PendingTokenExpiry: 5 * time.Minute,
SecureCookie: true,
SameSite: "lax",
})NOTE: make sure to set the AppName in your config.toml in standalone mode or in your AuthConfig in library mode, as it is used in the TOTP URI for authenticator apps.
API Reference
| Route | Auth Required | Description |
|---|---|---|
POST /totp/enable | ✅ Yes | Enable TOTP for authenticated user. Returns TOTP URI (QR code data) and backup codes. |
POST /totp/disable | ✅ Yes | Disable TOTP authentication for authenticated user. |
GET /totp/get-uri | ✅ Yes | Retrieve the TOTP URI for the authenticated user's current TOTP configuration. |
POST /totp/verify | ❌ No | Verify TOTP code during login. Requires valid pending token cookie. User and session are returned on success. |
POST /totp/verify-backup-code | ❌ No | Verify backup code during login. Requires valid pending token cookie. Single-use only. |
POST /totp/generate-backup-codes | ✅ Yes | Generate new backup codes for authenticated user. Invalidates previous codes. |
Authentication Notes
- ✅ Yes: Standard authentication required. User must be authenticated via session or other auth mechanism.
- ❌ No: Standard authentication NOT required, but special conditions apply. These routes require a valid TOTP pending token cookie set by the initial authentication attempt.
Endpoint Details
POST /totp/enable:
Request:
No request body required.
Response:
{
"totp_uri": "otpauth://totp/user@example.com?secret=ABCXYZ...&issuer=MyApp",
"backup_codes": ["aBcXyZ", ...]
}POST /totp/disable:
Request:
No request body required.
Response:
{
"message": "..."
}GET /totp/get-uri:
Response:
{
"totp_uri": "otpauth://totp/user@example.com?secret=ABCXYZ...&issuer=MyApp"
}POST /totp/verify:
Request:
{
"code": "123456",
"trust_device": true
}code: (Required) The 6-digit TOTP code to verifytrust_device: (Optional) If true, marks the device as trusted to skip TOTP verification on future logins for the configured duration
Response:
{
"user": {
/* ... */
},
"session": {
/* ... */
}
}POST /totp/verify-backup-code:
Request:
{
"code": "3oz4vtq7ci2n",
"trust_device": true
}code: (Required) The backup code to verify. Backup codes are single-use and will be invalidated after successful verification.trust_device: (Optional) If true, marks the device as trusted to skip TOTP verification on future logins for the configured duration
Response:
{
"user": {
/* ... */
},
"session": {
/* ... */
}
}POST /totp/generate-backup-codes:
Request:
No request body required.
Response:
{
"backup_codes": ["aBcXyZ", ...]
}Database Schema
This plugin creates the following database tables:
Table: totp
| Field | Type | Key | Description |
|---|---|---|---|
id | string | PK | Unique identifier for the TOTP record |
user_id | string | FK | Reference to the user |
secret | string | - | Encrypted TOTP secret key |
backup_codes | string | - | Serialized hashed backup codes |
enabled | boolean | - | Whether TOTP is enabled |
created_at | timestamp | - | Record creation time |
updated_at | timestamp | - | Record last update time |
Table: trusted_devices
| Field | Type | Key | Description |
|---|---|---|---|
id | string | PK | Unique identifier for the trusted device |
user_id | string | FK | Reference to the user |
token | string | - | Hashed device trust token |
user_agent | string | - | Device user agent |
expires_at | timestamp | - | When the device trust expires |
created_at | timestamp | - | Record creation time |
Migrations are automatically handled when the plugin is initialized.
Event Hooks
The TOTP plugin emits events for the following operations:
totp.enabledtotp.disabledtotp.verifiedtotp.backup_code_usedtotp.device_trusted
These events can be subscribed to via the event bus for logging, analytics, or custom business logic.
Security Considerations
- Secure Cookies: In production, always set
secure_cookie = trueto ensure cookies are only sent over HTTPS. - Pending Token Expiry: The pending token used to access verify routes expires in 10 minutes by default. Configure based on your security requirements.
- Backup Codes: Store backup codes securely. They are single-use and provide account recovery.
- Trusted Devices: Use appropriate
trusted_device_durationvalues. Shorter durations increase security but require more frequent TOTP verification. - Password Verification: Set
skip_verification_on_enable = falseto require password verification when enabling TOTP.
