经过快速搜索和阅读文档后,我在Django项目[Reference Link]中实现了Django-双因素身份验证。
它工作得很好,我正在使用谷歌验证器进行基于令牌的登录。当我想扩展库的登录方法时,问题就出现了。我想强制我的每个用户使用2-Factor-Auth作为强制。我没有使用任何注册措施,因此在登录时必须对用户进行检查。
问题是设计一个自定义登录机制,但我无法将此库与自定义登录结合起来。
附言:我有一个自定义的用户模型,目前我使用Django双因素身份验证附带的默认登录。
我不认为代码是必要的,所以我没有发布它,但如果需要,我可以分享它。
在仔细查看了库代码后,我能够在two_factor库中操作检查。
所以,看看two_factor
文件夹,很容易理解它只是一个类似于其他应用程序的Django应用程序。
我导航到我的虚拟环境venvLibsite-packagestwo_factorviewscore.py
中的库文件。正如文档中提到的,到目前为止,用户还没有强制设置2fa。
在CCD_ 3中有一个函数CCD_。IT检查2fa的设备可用性,只需添加用于重定向的else子句。
def done(self, form_list, **kwargs):
"""
Login the user and redirect to the desired page.
"""
# Check if remember cookie should be set after login
current_step_data = self.storage.get_step_data(self.steps.current)
remember = bool(current_step_data and current_step_data.get('token-remember') == 'on')
login(self.request, self.get_user())
redirect_to = self.get_success_url()
device = getattr(self.get_user(), 'otp_device', None)
response = redirect(redirect_to)
if device:
signals.user_verified.send(sender=__name__, request=self.request,
user=self.get_user(), device=device)
# Set a remember cookie if activated
if getattr(settings, 'TWO_FACTOR_REMEMBER_COOKIE_AGE', None) and remember:
# choose a unique cookie key to remember devices for multiple users in the same browser
cookie_key = REMEMBER_COOKIE_PREFIX + str(uuid4())
cookie_value = get_remember_device_cookie(user=self.get_user(),
otp_device_id=device.persistent_id)
response.set_cookie(cookie_key, cookie_value,
max_age=settings.TWO_FACTOR_REMEMBER_COOKIE_AGE,
domain=getattr(settings, 'TWO_FACTOR_REMEMBER_COOKIE_DOMAIN', None),
path=getattr(settings, 'TWO_FACTOR_REMEMBER_COOKIE_PATH', '/'),
secure=getattr(settings, 'TWO_FACTOR_REMEMBER_COOKIE_SECURE', False),
httponly=getattr(settings, 'TWO_FACTOR_REMEMBER_COOKIE_HTTPONLY', True),
samesite=getattr(settings, 'TWO_FACTOR_REMEMBER_COOKIE_SAMESITE', 'Lax'),
)
else:
return redirect('two_factor:setup')
return response
因此,只有当用户设置了2fa时,才能成功检查设备,但对于未经验证的用户来说,这永远不会是真的。
我完全理解会有一种更高效、更优雅的方法来完成上述任务,但由于我的知识和时间限制,我不得不这样做。如果我遇到,我会发布更新,我也欢迎对我的解决方案进行反馈。
django-otp的OTPMiddleware
提供了一个is_verified()
方法。根据文件,这种方法
可用于检查用户是否使用双因素身份验证登录。
我有一个与您类似的场景(自定义用户模型和django双因素身份验证的默认登录机制(,所以我做了以下操作:
- 将
LOGIN_REDIRECT_URL
设置为需要经过验证的用户的URL。例如,我们称之为"dashboard"
- 在仪表板视图中,执行以下操作:
def dashboard_view(request):
if request.user.is_verified():
# user logged in using two-factor
return render(request, "dashboard/template.html")
else:
# user not logged in using two-factor
return redirect("two_factor:setup")
"enginervix"的贡献非常有用,但是,只需进行一次身份验证并键入已知的django网址就可以绕过它。然而,这是第一个超级步骤。再加上一个带有"request.user.is_verified"复选框的standart base.html,在我看来这是一个完整的解决方案。我附上我的base.html作为一个例子。
我的想法是,我所有的自定义网页都是用扩展的base.html构建的。如果base.html只能用2FA访问,那么我所有的定制网页都只能由2FA访问。添加了一个特殊块"content_non_auth",用于在没有2FA的情况下管理用户帐户。
<!-- templates/base.html -->
<!DOCTYPE html>
<html lang="de">
<head>
...
</head>
<body>
<div class="container">
<header class="p-3 mb-3 border-bottom">
{% if request.user.is_verified %}
<a class="navbar-brand" href="{% url 'home' %}">
Sample Site Title</a>
{% else %}
<h3 style="color:blue;">Sample Site Tile</h3>
{% endif %}
</header>
<main>
{% if request.user.is_verified %}
{% block content %}
{% endblock %}
{% else %}
<h3>You are not logged in</h3>
{% block content_non_auth %}
<!-- Block for user accout management without 2FA -->`enter code here`
{% endblock %}
{% endif %}
</main>
</body>
</html>