gpt4 book ai didi

python - 在 Django/Django Rest 中添加两因素身份验证

转载 作者:行者123 更新时间:2023-12-04 03:36:08 25 4
gpt4 key购买 nike

我知道这个话题已被广泛讨论,但大多数示例都是关于标准 Django 模板中的两因素身份验证,而在我的情况下,我想将两因素身份验证添加到一个项目中,其中 Django 在后端用作 API,而前端是一个原生的 VueJS 应用程序。
对于与身份验证相关的所有内容,我使用内置的 Django session 身份验证,因为前端和后端都部署在同一台服务器上。
我的问题是 :如何向使用 django 作为 API 的项目添加两因素身份验证(使用 google 身份验证器或 yubikey)?
这是问题 :最简单的方法是让用户从前端登录,一旦用户从 /accounts/login 登录(内置 django 身份验证 View ),提交一个表单,用户必须在其中输入他们的代码。这种方法的问题是一旦用户登录 Django 就会创建一个 session ,所以 request.user.is_authenticated将返回 True即使用户还没有提交双因素代码,所以一切都取决于前端。我不喜欢这种方法,因为我担心有人可能会找到一种方法来避免提交双因素表单并在没有双因素身份验证的情况下在网站的其余部分导航(因为根据 Django,该 session 将经过身份验证)
我试过的:我仍然需要为此编写大部分代码,因为我想首先了解它的安全性。但这是我的方法:
第一种方法

  • 用户提交登录表单
  • 提交登录表单后,带有凭据的 POST 请求将发送到名为 /authenticate 的端点。在我的 Django 应用程序中。此端点将使用 Django 内置 authenticate()将检查这些凭据是否属于用户而不创建 session 的方法。
  • 如果凭据属于用户,则返回 True给用户。此时用户将提交带有2FA代码的表单,如果代码正确,则将请求发送到/accounts/login这将再次检查密码和电子邮件并实际登录用户并创建 session ,这次。

  • 第二种方法
    另一种更好的方法是覆盖 Django-Allauth 登录 View ,以便我可以添加对 token 的检查,例如(警告:伪代码):
    if provided_code == user_code:
    login()
    return HttpResponse({'Result': 'Logged in!'})
    else:
    return HttpResponse({'Result': 'incorrect code'})
    哪里 provided_code是用户提供的2FA代码和 user_code是我将从另一个函数(如 get_user_2fa_code(user))中检索的正确代码.
    我不是安全专家,但我没有想出更好的方法。会有多安全?有没有更好的方法将 2FA 身份验证添加到 Django 项目,其中 django 作为后端 API?
    Here is the login view :
    class LoginView(
    RedirectAuthenticatedUserMixin, AjaxCapableProcessFormViewMixin, FormView
    ):
    form_class = LoginForm
    template_name = "account/login." + app_settings.TEMPLATE_EXTENSION
    success_url = None
    redirect_field_name = "next"

    @sensitive_post_parameters_m
    def dispatch(self, request, *args, **kwargs):
    return super(LoginView, self).dispatch(request, *args, **kwargs)

    def get_form_kwargs(self):
    kwargs = super(LoginView, self).get_form_kwargs()
    kwargs["request"] = self.request
    return kwargs

    def get_form_class(self):
    return get_form_class(app_settings.FORMS, "login", self.form_class)

    def form_valid(self, form):
    success_url = self.get_success_url()
    try:
    return form.login(self.request, redirect_url=success_url)
    except ImmediateHttpResponse as e:
    return e.response

    def get_success_url(self):
    # Explicitly passed ?next= URL takes precedence
    ret = (
    get_next_redirect_url(self.request, self.redirect_field_name)
    or self.success_url
    )
    return ret

    def get_context_data(self, **kwargs):
    ret = super(LoginView, self).get_context_data(**kwargs)
    signup_url = passthrough_next_redirect_url(
    self.request, reverse("account_signup"), self.redirect_field_name
    )
    redirect_field_value = get_request_param(self.request, self.redirect_field_name)
    site = get_current_site(self.request)

    ret.update(
    {
    "signup_url": signup_url,
    "site": site,
    "redirect_field_name": self.redirect_field_name,
    "redirect_field_value": redirect_field_value,
    }
    )
    return ret

    最佳答案

    这可能会有所帮助..我不确定。大多数现有的 django 2fa 项目都按照你描述的方式工作 - 我建议检查他们如何做以获得更好的提示。

  • 首先使用 django.contrib.auth.authenticate 检查用户名/密码.此身份验证是凭据,但不会创建 session 。
  • 如果用户有 2FA- 将他们路由到页面以执行验证步骤
  • 验证步骤完成后 - 使用 django.contrib.auth.login 登录他们

  • 对于登录身份验证 View 并发布凭据 - 我做了这样的事情:
    class TwoFactorAwareLoginView(TemplateView):
    def post(self, request, *args, **kwargs):
    form = self.form_class(data=request.POST, request=request)
    if form.is_valid():
    username = form.cleaned_data.get("username")
    password = form.cleaned_data.get("password")
    user = authenticate(request, username=username, password=password)
    if user is not None:
    devices = <something to get your 2FA device blobs>
    if not devices: #no user devices- log them in
    login(request, user)
    return HttpResponseRedirect(reverse("cool-page"))
    else: #2FA devices exist- route them to verification view and perform auth_login once complete
    # add some context needed for verification view in session or context
    return HttpResponseRedirect(reverse("two-factor:verify-login"))
    return render(request, self.template_name, {"form": form})

    关于python - 在 Django/Django Rest 中添加两因素身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66879284/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com