MFA that's tougher than a fourteener. Two-factor authentication your users will actually enable.
Built for security-conscious organizations that value user experience
Works with Google Authenticator, Authy, 1Password, and any TOTP-compatible app.
10 single-use recovery codes for when devices are lost or unavailable.
One scan and done. Easier than finding parking downtown on a Saturday.
Users get a heads up before MFA enforcement. We're not monsters.
Automatically prompts for MFA on suspicious logins and new devices.
Every feature available via API, not just the UI.
Get MFA working in your app with these simple examples
// Setup MFA for user
const setupMFA = async () => {{
const {{ qrCode, secret, backupCodes }} =
await api.post('/users/mfa/setup');
// Show QR code to user
displayQRCode(qrCode);
// Show backup codes (we handle the UI)
showBackupCodes(backupCodes);
// Wait for user to scan and enter code
const verificationCode = await getUserInput();
// Enable MFA
const result = await api.post('/users/mfa/enable', {{
code: verificationCode
}});
if (result.success) {{
celebrate(); // 🎉
}}
}};// Enhanced login with MFA
const login = async (credentials) => {{
const loginResult = await api.post('/auth/sign_in', {{
email: credentials.email,
password: credentials.password
}});
if (loginResult.requires_mfa) {{
// Prompt for MFA code
const mfaCode = await promptForMFA();
const mfaResult = await api.post('/auth/verify_mfa', {{
session_token: loginResult.session_token,
mfa_code: mfaCode
}});
return mfaResult.access_token;
}}
return loginResult.access_token;
}};// Using our React hook
import {{ useMFA }} from '23blocks-react';
function MFASetup() {{
const {{
setupMFA,
enableMFA,
qrCode,
backupCodes,
isLoading
}} = useMFA();
const handleSetup = async () => {{
await setupMFA();
// QR code and backup codes are now available
}};
const handleEnable = async (code) => {{
await enableMFA(code);
router.push('/dashboard');
}};
return (
<MFASetupFlow
onSetup={{ '{' + '{' }}handleSetup{{ '}' + '}' }}
onEnable={{ '{' + '{' }}handleEnable{{ '}' + '}' }}
qrCode={{ '{' + '{' }}qrCode{{ '}' + '}' }}
backupCodes={{ '{' + '{' }}backupCodes{{ '}' + '}' }}
loading={{ '{' + '{' }}isLoading{{ '}' + '}' }}
/>
);
}}// Check MFA status and manage
const mfaStatus = await api.get('/users/mfa/status');
console.log(mfaStatus);
// {{
// enabled: true,
// backup_codes_remaining: 7,
// last_used: '2024-01-15T10:30:00Z',
// trusted_devices: 2
// }}
// Disable MFA (with confirmation)
await api.post('/users/mfa/disable', {{
confirmation_code: '123456'
}});
// Regenerate backup codes
const newCodes = await api.post('/users/mfa/regenerate_codes');
// Check if code is valid (without consuming it)
const isValid = await api.post('/users/mfa/validate', {{
code: '123456'
}});Numbers that matter from companies using our MFA
Urban Mobility Platform
Outdoor Recreation App
Common scenarios where MFA makes the biggest impact
Companies that need to meet strict security compliance standards.
Protecting accounts with access to sensitive data or financial information.
Teams that value their weekends and want security that "just works".
Companies that care about security but refuse to frustrate users.
Everything you need to implement and maintain MFA
Complete API documentation with request/response examples for all MFA endpoints
View MFA API Docs →Step-by-step integration tutorials for React, Vue, Angular, and vanilla JavaScript
View Integration Guide →Stop losing sleep over password breaches. Start protecting your users with MFA that actually works.
Get product updates, engineering posts, and new block announcements delivered to your inbox.