django-two-factor-auth 是 django 最成熟活跃的 mfa 方案,支持 totp、短信、语音、备份码;需正确配置 installed_apps 顺序、url 路由及 login_url,修复 qr 码需确保静态文件与模板加载,短信需自实现网关,admin 强制 mfa 需 patch 或手动覆盖,生产环境须预设应急恢复入口。

django-two-factor-auth 是 Django 生态中最成熟、维护最活跃的 MFA 实现方案,它支持 TOTP(Google Authenticator 类应用)、短信(需第三方服务)、电话语音、备份码等认证方式。直接集成它比自己手写 MFA 流程更安全、更省心,也避免踩权限绕过、会话劫持、时间偏移等常见坑。
安装与基础配置必须做对这三步
很多项目卡在登录页 404 或跳过第二步验证,问题基本出在这几步没配全:
- 运行
pip install django-two-factor-auth后,必须把two_factor加入INSTALLED_APPS,且位置要在django.contrib.auth之后、自定义 app 之前 -
urls.py中要显式 includetwo_factor.urls,路径建议固定为^account/two_factor/,不能只写^two_factor/—— 否则和 admin 的 URL 冲突,导致管理后台无法访问 -
LOGIN_URL必须设为'two_factor:login',而不是'login';否则@login_required重定向会绕过 MFA 流程
用户启用 TOTP 时提示 “QR code not found” 或空白页面
这是模板缺失或静态文件未加载导致的典型表现。django-two-factor-auth 的 QR 码生成依赖前端 JS 库 qrious 和后端 qrcode 包,但错误常出现在前端环节:
- 确认已执行
python manage.py collectstatic,且qrious.min.js已出现在STATIC_ROOT对应目录下(默认是static/two_factor/js/qrious.min.js) - 检查模板中是否漏掉了
{% load static %},以及<script src="%7B%%20static%20'two_factor/js/qrious.min.js'%20%%7D"></script> - 如果用的是自定义登录模板,必须继承
two_factor/core/base.html或手动补全<div id="qr-code"></div>和初始化脚本
短信/电话验证需要额外对接,别指望开箱即用
django-two-factor-auth 自带的 PhoneMethod 只提供接口契约,不内置任何运营商通道。你必须自行实现 send_sms 或 make_call 方法:
- 推荐用 Twilio:安装
twilio包,继承two_factor.gateways.twilio.Twilio并填入ACCOUNT_SID、AUTH_TOKEN和PHONE_NUMBER - 国内场景慎用阿里云短信 SDK 直接替换 Twilio 类——它的签名机制和模板变量语法和 Twilio 不兼容,容易触发 400 错误;建议单独写个
AliyunSMSBackend实现two_factor.gateways.base.SMSBackend接口 - 无论哪种方式,都要在
TWO_FACTOR_SMS_GATEWAY设置里明确指定类路径,例如'myapp.gateways.AliyunSMSBackend'
启用 MFA 后,Django Admin 登录失败或反复跳转
Admin 默认不走 two_factor:login,而是用自己的 admin:login。若想让管理员也强制 MFA,不能只靠中间件,得改两个地方:
- 在
urls.py中,把 admin 的 URL 改为path('admin/', admin.site.urls, name='admin'),并确保admin.site.login被重写为two_factor.views.LoginView.as_view() - 更稳妥的做法是:在
settings.py中设置TWO_FACTOR_PATCH_ADMIN = True,它会自动 monkey patch admin 登录视图——但仅适用于 Django ≤ 4.1;Django 4.2+ 需手动覆盖AdminSite.login属性 - 注意:启用后,超级用户首次登录会看到 “You have not configured two-factor authentication yet”,必须先完成设备绑定才能进入 admin
真正麻烦的不是集成步骤,而是用户设备丢失、备份码用完、或 TOTP 时间不同步时的恢复流程。别只依赖文档里的 manage.py tf_disable 命令——生产环境必须提前部署好管理员应急入口,比如一个独立于 MFA 的、带 IP 白名单和二次邮箱确认的重置页面。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











