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.

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.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

HTTP MethodRoute PathDescription
POST/totp/enableEnable TOTP for user
POST/totp/disableDisable TOTP for user
GET/totp/get-uriGet TOTP URI
POST/totp/verifyVerify TOTP code during login
POST/totp/verify-backup-codeVerify backup code during login
POST/totp/generate-backup-codesGenerate new backup codes

Authentication Notes

  • Authenticated endpoints (enable, disable, get-uri, generate-backup-codes): Standard authentication required. User must be authenticated via session or other auth mechanism.
  • Pending-token endpoints (verify, verify-backup-code): Standard authentication NOT required. These routes require a valid TOTP pending token cookie set by the initial authentication attempt.

Endpoint Details

POST /totp/enable:

No request body required.

Response:

{
  "totp_uri": "otpauth://totp/user@example.com?secret=ABCXYZ...&issuer=MyApp",
  "backup_codes": ["aBcXyZ", ...]
}

POST /totp/disable:

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:

No request body required.

Response:

{
  "backup_codes": ["aBcXyZ", ...]
}

Database Schema

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.


Plugin Capabilities

This plugin has the following hooks and capabilities:

  • totp.intercept — Intercepts authentication flow by setting the user a pending token cookie and returning a simple JSON response indicating a TOTP redirection. The client can then check for this response and redirect the user to the appropriate TOTP verification page.

Events

The TOTP plugin emits events that can be used to trigger custom business logic or integrate with other plugins via the event bus.

Event Hooks

The TOTP plugin emits events for the following operations:

  • totp.enabled — Fired when TOTP is enabled for a user
  • totp.disabled — Fired when TOTP is disabled for a user
  • totp.verified — Fired when a TOTP code is successfully verified
  • totp.backup_code_used — Fired when a backup code is used
  • totp.device_trusted — Fired when a device is marked as trusted

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

Route Mappings

When using the TOTP plugin, keep /totp/verify and /totp/verify-backup-code accessible to the pending-token flow (do not force authentication on these routes).


Security Recommendations

  • Secure Cookies — In production, always set secure_cookie = true to ensure cookies are only sent over HTTPS.
  • Pending Token Expiry — The pending token used to access verify routes expires in 5 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_duration values. Shorter durations increase security but require more frequent TOTP verification.
  • Password Verification — Set skip_verification_on_enable = false to require password verification when enabling TOTP.

Client Plugin

If you're using the Authula SDK, add the plugin to the SDK like so:

import { createClient } from "authula";
import { TOTPPlugin } from "authula/plugins";

export const authulaClient = createClient({
  url: "http://localhost:8080/auth",
  plugins: [
    // other plugins...
    new TOTPPlugin(),
  ],
});

On this page