0

在快速搜索和阅读文档后,我在我的一个 Django 项目 [参考链接] 中实现了 Django - Two Factor Authentication。

它很好用,我正在使用 Google Authenticator 进行基于令牌的登录。当我想扩展库的登录方法时,就会出现问题。我想强制我的每个用户使用 2-Factor-Auth 作为强制。我没有使用任何注册措施,因此必须在用户登录时进行检查。

问题是设计一个自定义登录机制,但我无法将此库与自定义登录合并。

PS:我有一个自定义用户模型,目前我使用的是 Django 两因素身份验证附带的默认登录。

虽然代码不是必需的,但我没有发布它,但如果需要,我可以分享它。

4

3 回答 3

2

通过查看库代码后,我能够操作 two_factor 库中的检查。

因此,查看two_factor文件夹很容易理解,它只不过是一个类似于其他的 Django 应用程序。

我导航到虚拟环境中的库文件venv\Lib\site-packages\two_factor\views\core.py。如文档中所述,到目前为止,用户还没有强制执行设置 2fa。

里面有LoginView(...)一个功能done。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 的情况下,设备检查才能成功,但对于未经验证的用户永远不会成功。

我完全理解将有一种更有效、更优雅的方法来完成上述任务,但由于我的知识和时间限制,我必须这样做。如果我遇到,我会发布更新,我也欢迎为我的解决方案提供反馈。

于 2021-04-24T14:09:45.770 回答
0

'engineervix' 的贡献非常有用,但是,它可以通过单一身份验证和输入已知的 django 网址简单地绕过。然而,这是超级第一步。结合标准 base.html 并检查“request.user.is_verified”,在我看来这是一个完整的解决方案。我附上我的 base.html 作为示例。

这个想法是我所有的自定义网页都是使用扩展 base.html 构建的。如果 base.html 只能通过 2FA 访问,那么我所有的自定义网页只能通过 2FA 访问。为没有 2FA 的用户帐户管理添加了一个特殊块“content_non_auth”。

<!-- 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>

于 2022-02-01T22:49:03.727 回答
0

django-two-factor-auth通过django -otpis_verified()的. 根据文档,这种方法OTPMiddleware

可用于检查用户是否使用双重身份验证登录。

我有一个和你类似的场景(自定义用户模型和 django-two-factor-auth的默认登录机制),所以我做了以下事情:

  1. 设置LOGIN_REDIRECT_URL为需要经过验证的用户的 URL。让我们称之为,例如,"dashboard"
  2. 在仪表板视图中,执行以下操作:
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")
于 2022-01-21T17:30:51.763 回答