App Logo
Plugins

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

RouteAuth RequiredDescription
POST /totp/enable✅ YesEnable TOTP for authenticated user. Returns TOTP URI (QR code data) and backup codes.
POST /totp/disable✅ YesDisable TOTP authentication for authenticated user.
GET /totp/get-uri✅ YesRetrieve the TOTP URI for the authenticated user's current TOTP configuration.
POST /totp/verify❌ NoVerify TOTP code during login. Requires valid pending token cookie. User and session are returned on success.
POST /totp/verify-backup-code❌ NoVerify backup code during login. Requires valid pending token cookie. Single-use only.
POST /totp/generate-backup-codes✅ YesGenerate 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 verify
  • 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/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

FieldTypeKeyDescription
idstringPKUnique identifier for the TOTP record
user_idstringFKReference to the user
secretstring-Encrypted TOTP secret key
backup_codesstring-Serialized hashed backup codes
enabledboolean-Whether TOTP is enabled
created_attimestamp-Record creation time
updated_attimestamp-Record last update time

Table: trusted_devices

FieldTypeKeyDescription
idstringPKUnique identifier for the trusted device
user_idstringFKReference to the user
tokenstring-Hashed device trust token
user_agentstring-Device user agent
expires_attimestamp-When the device trust expires
created_attimestamp-Record creation time

Migrations are automatically handled when the plugin is initialized.


Event Hooks

The TOTP plugin emits events for the following operations:

  • totp.enabled
  • totp.disabled
  • totp.verified
  • totp.backup_code_used
  • totp.device_trusted

These events can be subscribed to via the event bus for logging, analytics, or custom business logic.


Security Considerations

  1. Secure Cookies: In production, always set secure_cookie = true to ensure cookies are only sent over HTTPS.
  2. Pending Token Expiry: The pending token used to access verify routes expires in 10 minutes by default. Configure based on your security requirements.
  3. Backup Codes: Store backup codes securely. They are single-use and provide account recovery.
  4. Trusted Devices: Use appropriate trusted_device_duration values. Shorter durations increase security but require more frequent TOTP verification.
  5. Password Verification: Set skip_verification_on_enable = false to require password verification when enabling TOTP.

On this page