django-mfa
Second-factor authentication for Django: authenticator apps (TOTP), security keys and passkeys (WebAuthn), and recovery codes — with the enrollment pages, challenge screens, and enforcement middleware already written.
Add the app, the middleware, and a URL include, and your users have a second factor.
Your login view doesn’t change: django-mfa hooks Django’s own user_logged_in
signal, so whatever authenticates your users today keeps doing so.
INSTALLED_APPS += ["django_mfa"]
MIDDLEWARE += ["django_mfa.middleware.MfaMiddleware"]
urlpatterns += [path("mfa/", include("django_mfa.urls"))]
New here? Start with Getting started, then skim Flow and URLs to see what your users will actually go through.
Source code: https://github.com/MicroPyramid/django-mfa
Getting started
Guides
Reference
- Settings reference
- Public API
django_mfa.sessiondjango_mfa.registrydjango_mfa.models.Authenticatordjango_mfa.models.MfaExemptiondjango_mfa.conf.settingsdjango_mfa.utilsdjango_mfa.cryptodjango_mfa.handlesdjango_mfa.quicklogindjango_mfa.backends.WebAuthnBackenddjango_mfa.middleware.MfaMiddlewaredjango_mfa.ratelimit- Signals
- JSON API
- Security model
Project
- Upgrading from django-mfa 2.x/3.x
- 1. Django 4.2+ and Python 3.10+ are now required
- 2. U2F support is removed entirely
- 3.
UserOTP,UserRecoveryCodes, andU2FKeyare replaced byAuthenticator - 4.
request.session["verfied_otp"]/["verfied_u2f"]are replaced byrequest.session["mfa"] - 5. Nine URL names are gone
- 6. Host projects no longer set
u2f_pre_verify_user_pk/u2f_pre_verify_user_backend - 7.
MFA_FIDO2_RP_IDis now required for WebAuthn - 8. Migration
0007is irreversible – roll back from a backup, notmigrate - 9. TOTP now tolerates a small clock/window drift
- 10. Recovery codes are hashed at rest – migrated codes are the exception, until regenerated
- 11. Passwordless login requires adding
WebAuthnBackendtoAUTHENTICATION_BACKENDS - 12. Security fixes in 4.0.1 that change observable behaviour
- 4.2.0: factor changes now require a recent challenge
- 4.5.0: rate-limit counters move to the database, and two behaviour changes
- Contributing