Two Factor

The two-factor plugin stores a two-factor record for the user and adds TOTP, OTP, backup-code, and trusted-device verification flows.

This page documents the current Ruby port behavior. Ruby uses snake_case option names and auth.api method names; HTTP paths and JSON keys keep the upstream wire shape where implemented.

Configure

config/auth.rb
require "better_auth"

auth = BetterAuth.auth(
  secret: ENV.fetch("BETTER_AUTH_SECRET"),
  base_url: ENV.fetch("BETTER_AUTH_URL", "http://localhost:3000"),
  plugins: [
    BetterAuth::Plugins.two_factor(
      otp_options: {
        send_otp: ->(data, _ctx = nil) {
          Mailer.two_factor(data[:user]["email"], data[:otp]).deliver_now
        }
      }
    )
  ]
)

Usage

server.rb
enabled = auth.api.enable_two_factor(
  headers: { "cookie" => request.env["HTTP_COOKIE"] },
  body: { password: "password123" }
)

auth.api.verify_totp(
  headers: { "cookie" => request.env["HTTP_COOKIE"] },
  body: { code: params[:code] }
)

sign_in = auth.api.sign_in_email(
  body: { email: "ada@example.com", password: "password123" },
  return_headers: true
)

two_factor_cookie = sign_in.fetch(:headers).fetch("set-cookie")

auth.api.send_two_factor_otp(headers: { "cookie" => two_factor_cookie })
auth.api.verify_two_factor_otp(
  headers: { "cookie" => two_factor_cookie },
  body: { code: params[:code] }
)

Routes

MethodPathRuby API method
POST/two-factor/enableauth.api.enable_two_factor
POST/two-factor/disableauth.api.disable_two_factor
POST/totp/generateauth.api.generate_totp
POST/two-factor/get-totp-uriauth.api.get_totp_uri
POST/two-factor/verify-totpauth.api.verify_totp
POST/two-factor/send-otpauth.api.send_two_factor_otp
POST/two-factor/verify-otpauth.api.verify_two_factor_otp
POST/two-factor/verify-backup-codeauth.api.verify_backup_code
POST/two-factor/generate-backup-codesauth.api.generate_backup_codes

Options

Current Ruby options accepted by BetterAuth::Plugins.two_factor:

  • backup_code_options
  • otp_options
  • totp_options
  • schema
  • skip_verification_on_enable
  • issuer
  • trust_device_max_age
  • send_otp
  • digits
  • period
  • two_factor_cookie_max_age

Support Notes

  • The examples above are based on Ruby plugin source and tests in packages/better_auth.
  • If an upstream section is not represented here, treat it as not yet documented or not yet supported by the Ruby port until the matching Ruby implementation exists.

On this page