TOTP Standard
Works with any authenticator app
Backup Codes
Recovery codes for lost devices
Rate Limited
Brute-force protection built-in
Enforceable
Require 2FA for specific roles
Overview
Two-factor authentication (2FA) adds an extra layer of security by requiring users to provide a time-based one-time password (TOTP) in addition to their regular password. Users can use authenticator apps like Google Authenticator, Authy, or 1Password.
How 2FA Works
User Enables 2FA
Users enable 2FA through the Sylphx Console account settings or your app's settings page using the platform API.
Scan QR Code
User scans the QR code with their authenticator app (or enters secret manually).
Verify Code
User enters a 6-digit code from their app to verify setup and receives backup codes.
Login with 2FA
On subsequent logins, the SDK automatically handles the 2FA challenge.
2FA Setup
Sign In with 2FA
When a user with 2FA enabled signs in, the SDK automatically handles the 2FA challenge. Use the useSignInForm headless hook for full control:
'use client'
import { useSignInForm } from '@sylphx/sdk/react'
export function LoginForm() {
const {
form,
setEmail,
setPassword,
setOtp,
handlePasswordSubmit,
handleTwoFactorVerify,
isLoading,
error,
pendingTwoFactor,
} = useSignInForm({ afterSignInUrl: '/dashboard' })
// 2FA verification step
if (pendingTwoFactor) {
return (
<form onSubmit={handleTwoFactorVerify}>
<h2>Enter Authentication Code</h2>
<p className="text-muted-foreground mb-4">
Enter the 6-digit code from your authenticator app
</p>
{error && <div className="text-red-500 mb-4">{error}</div>}
<input
type="text"
placeholder="000000"
value={form.otp}
onChange={e => setOtp(e.target.value)}
maxLength={6}
autoFocus
className="text-center text-2xl tracking-widest"
/>
<button type="submit" disabled={isLoading}>
{isLoading ? 'Verifying...' : 'Verify'}
</button>
</form>
)
}
// Initial login step
return (
<form onSubmit={handlePasswordSubmit}>
{error && <div className="text-red-500 mb-4">{error}</div>}
<input
type="email"
placeholder="Email"
value={form.email}
onChange={e => setEmail(e.target.value)}
/>
<input
type="password"
placeholder="Password"
value={form.password}
onChange={e => setPassword(e.target.value)}
/>
<button type="submit" disabled={isLoading}>
{isLoading ? 'Signing in...' : 'Sign In'}
</button>
</form>
)
}Automatic 2FA Detection
useSignInForm hook automatically detects when 2FA is required and sets pendingTwoFactor to the user's info. You just need to render the OTP input and call handleTwoFactorVerify.Backup Codes
Backup codes allow users to access their account if they lose their authenticator device. Backup codes are provided when 2FA is first enabled and can be regenerated through the Console.
// Using a backup code to sign in
// Backup codes work the same as TOTP codes in the sign-in flow
import { useSignInForm } from '@sylphx/sdk/react'
function LoginWithBackupCode() {
const { setOtp, handleTwoFactorVerify, pendingTwoFactor } = useSignInForm({
afterSignInUrl: '/dashboard'
})
// When 2FA is required, user can enter a backup code
// instead of the TOTP code from their authenticator app
if (pendingTwoFactor) {
return (
<form onSubmit={handleTwoFactorVerify}>
<input
type="text"
placeholder="Enter backup code (e.g., XXXX-XXXX)"
onChange={e => setOtp(e.target.value)}
/>
<button type="submit">Use Backup Code</button>
</form>
)
}
}Backup Code Usage
Managing 2FA
2FA setup, configuration, and disabling is managed through the Sylphx Console or your app's account settings using platform-level APIs. This ensures sensitive security operations are properly validated.
Platform-Level Operations
- Enable 2FA with QR code setup
- Generate and view backup codes
- Regenerate backup codes
- Disable 2FA (requires code verification)
Check 2FA Status
2FA status can be checked through your backend or Console API. The SDK focuses on handling the authentication flow - when a user with 2FA signs in, the pendingTwoFactor state indicates that verification is required.
import { useSignInForm } from '@sylphx/sdk/react'
function LoginForm() {
const { pendingTwoFactor, ...rest } = useSignInForm({
afterSignInUrl: '/dashboard'
})
// pendingTwoFactor is set when login succeeds but 2FA is required
// { userId: string, email: string }
if (pendingTwoFactor) {
// User has 2FA enabled, show OTP input
return <TwoFactorForm {...rest} />
}
return <CredentialsForm {...rest} />
}Best Practices
| Property | Type | Description |
|---|---|---|
Encourage 2FA | Recommended | Prompt users to enable 2FA after signup, especially for sensitive apps |
Require for admins | Recommended | Enforce 2FA for admin accounts |
Backup codes | Required | Always provide backup codes and remind users to save them |
Recovery options | Required | Have a support process for users who lose both device and backup codes |
Rate limiting | Automatic | Platform automatically rate-limits 2FA attempts |