Passwordless Authentication
Choose and implement AuthOS passkey or magic link authentication
This guide demonstrates passwordless authentication using passkeys (WebAuthn/FIDO2) and magic links. These flows avoid password handling, but their security and usability depend on enrollment, recovery, browser or email security, and deployment configuration.
Overview
AuthOS supports two passwordless authentication methods:
- Passkeys (WebAuthn) - Biometric authentication using Touch ID, Face ID, Windows Hello, or hardware security keys
- Magic Links - One-time email links for authentication without passwords
Both methods avoid a memorized password in the described flow. Their security properties depend on implementation, browser or email-channel security, recovery design, and deployment configuration; this guide does not provide a general security guarantee.
Prerequisites
Before implementing passwordless authentication:
- Install the SDK:
npm install @drmhse/sso-sdk - Initialize the SSO client with your platform URL
- Ensure your application uses HTTPS (required for WebAuthn)
Choose a passwordless mechanism
Choose the method whose trust boundary and recovery model match your application before opening implementation details.
| Mechanism | Choose it when | Implementation |
|---|---|---|
| Passkeys (WebAuthn) | Your users have compatible browsers or authenticators and you can provide an independently tested recovery path. | Implement passkeys |
| Magic links | Email possession is an acceptable authentication factor and your delivery, expiry, and replay controls are ready. | Implement magic links |
You can offer both methods, but do not silently turn a failed passkey operation into an email login. Explain the fallback and let the user choose it.
Passkeys (WebAuthn) Authentication
The passkey flow moved to Implement passkeys.
Browser Compatibility Check
See the browser compatibility check.
Registering a Passkey
Logging In with a Passkey
See Logging in with a passkey.
Complete React Passkey Implementation
The complete component moved to Implement passkeys.
Magic Link Authentication
The email-link flow moved to Implement magic links.
Requesting a Magic Link
Verifying a Magic Link
Complete React Magic Link Implementation
The complete components moved to Implement magic links.
Best Practices
Passkey Security
Review passkey security.
Magic Link Security
Review magic-link security.
User Experience
- Progressive enhancement: Detect browser capabilities and offer appropriate methods
- Clear instructions: Guide users through the authentication process
- Alternative methods: Always provide fallback authentication options
- Loading states: Show clear feedback during authentication
- Error messages: Provide actionable error messages
Implementation Checklist
- Check browser support before showing passkey options
- Implement proper error handling for WebAuthn exceptions
- Configure appropriate magic link expiration times
- Add rate limiting for magic link requests
- Test on multiple devices and browsers
- Provide clear user instructions
- Implement fallback authentication methods
- Monitor authentication success rates
- Handle edge cases (expired links, cancelled authentication)
Combining Methods
For the best user experience, combine multiple passwordless methods:
export function UnifiedPasswordlessLogin() {
const [email, setEmail] = useState('');
const [method, setMethod] = useState<'passkey' | 'magic_link'>('passkey');
const hasPasskeySupport = sso.passkeys.isSupported();
// Auto-select magic link if passkeys not supported
useEffect(() => {
if (!hasPasskeySupport) {
setMethod('magic_link');
}
}, [hasPasskeySupport]);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (method === 'passkey' && hasPasskeySupport) {
// Try passkey login
try {
const result = await sso.passkeys.login(email);
// Handle success
} catch (error) {
// Fallback to magic link on error
console.log('Passkey failed, sending magic link');
await sso.magicLinks.request({ email });
}
} else {
// Use magic link
await sso.magicLinks.request({ email });
}
};
return (
<form onSubmit={handleSubmit}>
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
/>
{hasPasskeySupport && (
<div className="method-selector">
<label>
<input
type="radio"
checked={method === 'passkey'}
onChange={() => setMethod('passkey')}
/>
Use Passkey (Touch ID / Face ID)
</label>
<label>
<input
type="radio"
checked={method === 'magic_link'}
onChange={() => setMethod('magic_link')}
/>
Email me a magic link
</label>
</div>
)}
<button type="submit">
{method === 'passkey' ? 'Sign in with Passkey' : 'Send Magic Link'}
</button>
</form>
);
}
Troubleshooting
Passkey Issues
Use Passkey issues.
Magic Link Issues
Use Magic-link issues.
Related Documentation
- Authentication Module Reference - Complete API reference
- Authentication Flows Guide - OAuth and token management
- Password Authentication Guide - Traditional password flows