- Hardware security keys (YubiKey, Google Titan, etc.)
- Platform authenticators (Touch ID, Face ID, Windows Hello)
- Passkeys for passwordless authentication
Installation
WebAuthn support requires thefido2 package:
Configuration
WebAuthn is disabled by default. Enable it insettings.py:
settings.py
Development Setup
For local development onlocalhost:
settings.py
URL Endpoints
WebAuthn URLs are available at:/accounts/mfa/webauthn/add/- Add a new WebAuthn authenticator/accounts/mfa/webauthn/- List all WebAuthn authenticators/accounts/mfa/webauthn/<pk>/edit/- Edit authenticator name/accounts/mfa/webauthn/<pk>/delete/- Remove an authenticator/accounts/mfa/webauthn/login/- Passwordless login endpoint/accounts/mfa/webauthn/signup/- Passwordless signup endpoint/accounts/mfa/webauthn/reauthenticate/- Reauthentication endpoint
Adding a WebAuthn Authenticator
Flow
- User navigates to
/accounts/mfa/webauthn/add/ - Server generates a challenge and registration options
- User’s browser/device prompts for authentication (fingerprint, security key, etc.)
- Device creates a new key pair and returns the public key
- Server validates and stores the public key
Template Example
templates/mfa/webauthn/add_form.html
Passkey Login (Passwordless)
Passkeys allow users to log in without entering a username or password.Enable Passkey Login
settings.py
How It Works
- User clicks “Sign in with passkey” button
- Browser prompts user to select a passkey
- User authenticates (fingerprint, face, security key)
- Server validates the signature and logs user in
Implementation Example
templates/account/login.html
Passkey Signup
Users can create an account using only a passkey, no password required.Requirements
settings.py
Passkey signup requires email verification by code because the traditional email verification link approach needs a password, which passkey users don’t have.
Programmatic Usage
Begin Registration
Complete Registration
Begin Authentication
Complete Authentication
List User’s Authenticators
Customizing the Adapter
Customize WebAuthn behavior by overriding the adapter:myapp/adapter.py
settings.py
Forms Customization
Override WebAuthn forms:settings.py
Custom Add Form
myapp/forms.py
Database Model
WebAuthn credentials are stored in theAuthenticator model:
data field stores:
Security Features
Phishing Resistance
WebAuthn credentials are bound to your domain. They won’t work on phishing sites:User Verification
For passwordless flows, require user verification (biometric/PIN):Attestation
WebAuthn supports attestation to verify the authenticator’s authenticity. Thefido2 library handles this automatically.
Browser Support
WebAuthn is supported in:- Chrome/Edge 67+
- Firefox 60+
- Safari 13+
- Opera 54+
Feature Detection
Common Issues
”Localhost not secure” Error
In development, set:Credentials Not Working Across Subdomains
Set the RP ID to the parent domain:User Verification Fails
Some authenticators don’t support user verification. For non-passwordless flows, use:Testing
WebAuthn requires HTTPS orlocalhost. For testing:
- Use
python manage.py runserver(localhost) - Or use a tool like
ngrokfor HTTPS tunneling - Or configure
MFA_WEBAUTHN_ALLOW_INSECURE_ORIGIN = True
Virtual Authenticators
Chrome DevTools supports virtual authenticators for testing:- Open DevTools → More Tools → WebAuthn
- Enable virtual authenticator environment
- Add a virtual authenticator
- Test WebAuthn flows without physical hardware
Related
- TOTP Authentication - Time-based codes
- Recovery Codes - Backup authentication
- Configuration - All MFA settings
