OTP & 2FA Authentication System
ClawPlate provides a comprehensive OTP (One-Time Password) and 2FA (Two-Factor Authentication) system built on top of Supabase Auth. This feature enhances security by requiring users to verify their identity through multiple factors.
Overview
The OTP system supports multiple authentication methods:
- Email OTP: 6-digit codes sent via email
- SMS OTP: 6-digit codes sent via SMS (requires Supabase SMS configuration)
- Magic Links: Passwordless authentication via email links
- 2FA Integration: Two-factor authentication for enhanced security
Features
✅ Multi-Method Support
- Email-based OTP verification
- SMS-based OTP verification
- Magic link authentication
- Seamless integration with existing auth flow
✅ Enhanced Security
- Time-limited codes (configurable expiration)
- Rate limiting and cooldown periods
- Secure code generation and validation
- Protection against brute force attacks
✅ User Experience
- Auto-submit on completion
- Paste support for codes
- Keyboard navigation (arrow keys, backspace)
- Visual feedback (loading states, errors, success)
- Responsive design for all devices
✅ Developer Friendly
- TypeScript support
- Composable architecture
- Toast notifications
- Error handling
- Customizable UI components
Implementation Architecture
Core Components
├── composables/
│ ├── useAuth.ts # Main authentication composable
│ └── useToast.ts # Toast notification system
├── components/
│ ├── SupabaseOtpForm.vue # OTP form component
│ └── OAuthButton.vue # Social login buttons
└── pages/
└── auth/
├── login.vue # Login page with OTP integration
└── callback.vue # Auth callback handlerAuthentication Flow
Initial Authentication
- User chooses between email/password or magic link
- For magic link: OTP code is sent to email
- For 2FA: OTP code is sent after successful password verification
OTP Verification
- 6-digit code input with real-time validation
- Auto-submit when all digits are entered
- Resend functionality with cooldown timer
Session Management
- Automatic session creation on successful verification
- Redirect to intended destination
- Persistent login options
Configuration
Supabase Setup
Ensure your Supabase project is configured for OTP:
-- Enable OTP in your Supabase dashboard
-- Go to Authentication > Settings > Auth Providers
-- Enable "Enable email confirmations"
-- Configure email templatesEnvironment Variables
# Required for OTP functionality
SUPABASE_URL=your_supabase_url
SUPABASE_ANON_KEY=your_supabase_anon_key
# Optional: For SMS OTP (requires Supabase SMS setup)
SUPABASE_SMS_PROVIDER=twilio # or messagebirdEmail Templates
Configure email templates in Supabase Dashboard:
- Magic Link Template
<h2>Sign in to {{ .SiteName }}</h2>
<p>Click this link to sign in:</p>
<p><a href="{{ .ConfirmationURL }}">Sign In</a></p>
<p>Or enter this code: <strong>{{ .Token }}</strong></p>- OTP Code Template
<h2>Your verification code</h2>
<p>Your verification code is: <strong>{{ .Token }}</strong></p>
<p>This code will expire in 5 minutes.</p>Usage Examples
Basic OTP Implementation
<template>
<div class="auth-container">
<!-- Tab Selection -->
<div class="auth-tabs">
<button @click="activeTab = 'password'">Password</button>
<button @click="activeTab = 'otp'">Magic Link</button>
</div>
<!-- OTP Form -->
<SupabaseOtpForm
v-if="activeTab === 'otp'"
type="email"
:redirect-to="/dashboard"
@success="handleOtpSuccess"
@error="handleOtpError"
/>
</div>
</template>
<script setup lang="ts">
const activeTab = ref<'password' | 'otp'>('password')
const handleOtpSuccess = async (user: any, session: any) => {
// Handle successful OTP verification
console.log('User authenticated:', user)
await navigateTo('/dashboard')
}
const handleOtpError = (error: string) => {
// Handle OTP errors
console.error('OTP Error:', error)
}
</script>Advanced 2FA Integration
<script setup lang="ts">
const { signIn, loading } = useAuth()
const { toast } = useToast()
// Step 1: Regular login
const handleEmailLogin = async () => {
const result = await signIn(email, password)
if (result.requires2FA) {
// Show OTP form for 2FA
show2FAForm.value = true
} else if (result.success) {
// Direct login success
await navigateTo('/dashboard')
}
}
// Step 2: 2FA verification
const handle2FAVerification = async (code: string) => {
const result = await verify2FA(code)
if (result.success) {
await navigateTo('/dashboard')
}
}
</script>Security Considerations
Code Generation
- Codes are cryptographically secure random numbers
- 6-digit codes provide good balance of security and usability
- Codes expire after 5 minutes by default
Rate Limiting
// Built-in Supabase rate limiting
// - 5 attempts per hour per email
// - Cooldown periods between resend requests
// - Automatic blocking of suspicious activityBest Practices
- Always use HTTPS in production
- Implement proper error handling for network issues
- Use secure redirects to prevent open redirect attacks
- Log authentication events for security monitoring
- Implement session management with appropriate timeouts
API Reference
useAuth Composable
interface AuthComposable {
// OTP Methods
sendOTP(email: string, type: 'email' | 'sms'): Promise<AuthResult>
verifyOTP(email: string, code: string): Promise<AuthResult>
// Magic Link Methods
sendMagicLink(email: string, redirectTo?: string): Promise<AuthResult>
// 2FA Methods
enable2FA(): Promise<AuthResult>
disable2FA(): Promise<AuthResult>
verify2FA(code: string): Promise<AuthResult>
// State
loading: Ref<boolean>
user: Ref<User | null>
session: Ref<Session | null>
}Events
The OTP system emits several events for integration:
interface OTPEvents {
'submit': (code: string) => void // Code submitted
'resend': () => void // Resend requested
'complete': (code: string) => void // Code completed
'change': (code: string) => void // Code changed
'error': (message: string) => void // Error occurred
'success': (user: User) => void // Success
}Customization
Styling
The OTP components use Tailwind CSS classes and can be customized:
<SupabaseOtpForm
class="custom-otp-form"
:input-class="custom-input-style"
:button-class="custom-button-style"
/>Behavior
<SupabaseOtpForm
:length="8" // 8-digit codes instead of 6
:auto-submit="false" // Disable auto-submit
:resend-cooldown="60" // 60 second cooldown
:use-toast="false" // Disable toast notifications
/>Testing
Unit Tests
// Test OTP code validation
describe('OTP Validation', () => {
test('validates 6-digit codes', () => {
expect(isValidOTP('123456')).toBe(true)
expect(isValidOTP('12345')).toBe(false)
expect(isValidOTP('1234567')).toBe(false)
})
})Integration Tests
// Test OTP flow
describe('OTP Authentication Flow', () => {
test('sends OTP and verifies code', async () => {
// Send OTP
const sendResult = await sendOTP('test@example.com')
expect(sendResult.success).toBe(true)
// Verify OTP (in real tests, you'd get this from email)
const verifyResult = await verifyOTP('test@example.com', '123456')
expect(verifyResult.success).toBe(true)
})
})Troubleshooting
Common Issues
Codes not received
- Check email spam/junk folders
- Verify email configuration in Supabase
- Check rate limiting settings
Invalid code errors
- Ensure code hasn't expired (5 minute limit)
- Check for typos in email address
- Verify Supabase configuration
Resend cooldown issues
- Implement proper cooldown UI feedback
- Check rate limiting configuration
- Consider implementing progressive delays
Debug Mode
Enable debug logging for development:
// In your nuxt.config.ts
export default defineNuxtConfig({
runtimeConfig: {
public: {
authDebug: process.env.NODE_ENV === 'development'
}
}
})Production Deployment
Checklist
- [ ] Configure email templates in Supabase
- [ ] Set up proper domain verification
- [ ] Configure SMTP settings (if using custom provider)
- [ ] Test OTP flow in production environment
- [ ] Monitor authentication metrics
- [ ] Set up error alerting
Monitoring
Track these metrics in production:
- OTP success/failure rates
- Average verification time
- Resend request frequency
- Failed attempt patterns
- Session duration after OTP verification
Support
For issues related to OTP functionality:
- Check Supabase Auth logs
- Verify email delivery status
- Review rate limiting settings
- Test with different email providers
- Contact support with specific error messages
The OTP system provides a secure, user-friendly authentication method that enhances your application's security while maintaining excellent user experience.