Registry / auth-security / django-two-factor-auth

django-two-factor-auth

JSON →
library1.18.1pypypi✓ verified 25d ago

Complete Two-Factor Authentication for Django. Built on top of the django-otp framework and Django's built-in authentication system, it offers easy integration into most Django projects. Inspired by Google's Two-Step Authentication, it supports various methods including token generator apps (like Google Authenticator), SMS, call, and YubiKey. The library is actively maintained with frequent releases, typically every few months.

pip install django-two-factor-auth
INSTALL
IMPORT
SIG · DJANGO-TWO-FACTOR-
D
django-two-factor-auth
auth-securitypythonv1.18.1
Install
5.4s avg
Import
Disk
91MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v1.18.1 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.915 runs
installs and imports cleanly · install 0.0s · import 0.000s · 93.2MB
glibc
py 3.103.915 runs
installs and imports cleanly · install 5.4s · import 0.000s · 94MB
91MB installed
● package 91MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

urlpatterns
from two_factor.urls import urlpatterns
from two_factor.urls import urlpatterns

Install the library, add `django_otp` and `two_factor` (and any desired plugins) to `INSTALLED_APPS`, and ensure `OTPMiddleware` is in `MIDDLEWARE`. Then, configure `LOGIN_URL` and `LOGIN_REDIRECT_URL` to point to the library's views, and include its URL patterns in your project's `urls.py`. Remember to run `python manage.py migrate` after setup.

import os # settings.py # Add required apps, ensuring 'two_factor' is listed after django_otp plugins INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'django_otp', 'django_otp.plugins.otp_static', 'django_otp.plugins.otp_totp', # Optional plugins: # 'django_otp.plugins.otp_email', # For email tokens # 'two_factor.plugins.phonenumber', # For SMS/call tokens # 'two_factor.plugins.email', # For email tokens (alternative) # 'two_factor.plugins.yubikey', # For YubiKey support # 'webauthn', # For WebAuthn support 'two_factor', ] # Add OTP middleware after AuthenticationMiddleware MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django_otp.middleware.OTPMiddleware', # Must be after AuthenticationMiddleware 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] # Point to the two-factor authentication login/profile URLs LOGIN_URL = 'two_factor:login' LOGIN_REDIRECT_URL = 'two_factor:profile' # Optional: Configure email backend if using email tokens EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' DEFAULT_FROM_EMAIL = os.environ.get('DEFAULT_FROM_EMAIL', 'webmaster@localhost') # urls.py from django.contrib import admin from django.urls import path, include from two_factor.urls import urlpatterns as tf_urls urlpatterns = [ path('admin/', admin.site.urls), path('', include(tf_urls)), # Include two-factor URLs at the root or desired path # path('account/', include(tf_urls)), # Alternative: include at a specific path ] # To integrate with Django Admin (optional, and usually patched automatically) # from two_factor.admin import AdminSiteOTPRequiredMixin # class OTPAdminSite(AdminSiteOTPRequiredMixin, admin.AdminSite): # pass # admin.site = OTPAdminSite() # Replace default admin site if needed, often not required.
Debug
Known issues
breakingIn version 1.14.0, the phone capability was moved to a separate plugin. If you used phone-based authentication, you must add 'two_factor.plugins.phonenumber' to your INSTALLED_APPS to restore this functionality.
fix
Add 'two_factor.plugins.phonenumber' to your `INSTALLED_APPS` setting.
affects: >=1.14.0
gotchaThe `django_otp.middleware.OTPMiddleware` must be placed in `MIDDLEWARE` *after* `django.contrib.auth.middleware.AuthenticationMiddleware`. Incorrect ordering can lead to authentication issues.
fix
Ensure `OTPMiddleware` is correctly positioned after `AuthenticationMiddleware` in your `settings.py`.
affects: All versions
gotchaIf using optional authentication methods (e.g., SMS, email, YubiKey, WebAuthn), ensure their respective plugins (e.g., `django_otp.plugins.otp_email`, `two_factor.plugins.phonenumber`) are correctly listed in `INSTALLED_APPS` and any necessary extra dependencies are installed.
fix
Review the documentation for the specific authentication method and add the required plugin to `INSTALLED_APPS` and install extra packages.
affects: All versions
breakingIn version 1.16.0, the minimal `webauthn` dependency was upgraded to 2.0, which removed its `pydantic` dependency. If you were relying on `pydantic` through `webauthn`, you might need to add it as a direct dependency.
fix
If `pydantic` is still needed for other parts of your project, install it directly (`pip install pydantic`).
affects: >=1.16.0
gotchaTo prevent circumvention of two-factor authentication, ensure that any other login routes in your project (e.g., `django.contrib.auth.urls`) are removed or disabled once `django-two-factor-auth` is configured as the primary login.
fix
Carefully review your project's `urls.py` and remove or comment out conflicting login URL patterns, especially `path('accounts/', include('django.contrib.auth.urls'))` if it's not being explicitly handled.
affects: All versions
gotchaPrior to 1.18.0, the documentation for setting up YubiKey support or email gateways occasionally missed informing users to add the corresponding `django-otp` or `two_factor` plugin to `INSTALLED_APPS`. This was fixed in docs, but the underlying common mistake remains.
fix
Always ensure relevant plugins (`django_otp.plugins.otp_yubikey`, `two_factor.plugins.email`, etc.) are in `INSTALLED_APPS`.
affects: <1.18.0 (docs), All versions (common mistake)
gotchaAn infinite redirect issue with `AdminSiteOTPRequiredMixin` on the admin site was fixed in 1.18.0. If you are using this mixin, ensure you are on a compatible version to avoid login loops.
fix
Upgrade to `django-two-factor-auth` version 1.18.0 or newer if using `AdminSiteOTPRequiredMixin`.
affects: <1.18.0
Upgrade
Version history
1.18.1latest on PyPI · released Sep 27, 2025
Audit
Dependencies
django-otprequiredCore one-time password framework.
qrcoderequiredUsed for generating QR codes for TOTP setup.
django-phonenumber-fieldoptionalRequired for phone number capabilities (SMS, call).
phonenumbersoptionalRequired by django-phonenumber-field.
phonenumbersliteoptionalAlternative to phonenumbers, required by django-phonenumber-field.
webauthnoptionalFor WebAuthn (FIDO2) support.
django-otp-yubikeyoptionalFor YubiKey hardware token support.
PillowoptionalOptional, for generating PNG QR codes (default is SVG).
Agent activity
25 hits · last 30 days
node
22
Amazon
1
OpenAI (training)
1
Resources
django-two-factor-auth — pip install django-two-factor-auth · libregistry