You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何重写Django双因素认证默认登录成功响应

Django双因素认证登录后无法返回自定义HttpResponse的问题

我在登录视图中使用Django Two Factor Authorization,通过插件管理器注册了TwoFactorPlugin。目前遇到的问题是:尽管我在视图中返回自定义的HttpResponse,系统却始终跳转到LOGIN_REDIRECT_URL;若移除该配置,则会默认重定向到accounts/profile/(双因素认证的默认登录成功地址)。请问是否可以重写此逻辑以返回视图的HttpResponse?是否有其他实现方法或建议?

views.py

from two_factor.views import LoginView as TwoFactorLoginView

@login_required
def login_success(request):
    success_message = f"User logged in successfully."
    return HttpResponse(success_message)


class TwoFactor_LoginView(TwoFactorLoginView):
    def form_valid(self, form):
        response = super().form_valid(form)
        # plugin_response is an HttpResponse return from the plugin "two_factor"
        plugin_response = PluginManager.perform_action(
            "two_factor",
            self.request,
            email=self.request.user.email,
            password=form.cleaned_data.get("password"),
            token=self.request.POST.get("token"),
        )
        # If the plugin action returns an HttpResponse, use it instead
        if isinstance(plugin_response, HttpResponse):
            return plugin_response
        return response

urls.py

path("login/", TwoFactor_LoginView.as_view(), name="login"),
path("login_success/", login_success, name="login_success"),

settings.py

LOGIN_URL = "login/"
LOGIN_REDIRECT_URL = "/login_success/"

解决方案

问题核心是TwoFactorLoginView父类的form_valid方法在执行时,已经完成登录并生成了重定向响应,你后续返回的自定义响应会被覆盖。以下是两种可行的解决思路:

方法1:重写get_success_url并调整form_valid逻辑

如果插件返回的是重定向地址,或你需要动态控制跳转目标,可以通过重写get_success_url实现,同时调整form_valid避免父类的重定向覆盖:

class TwoFactor_LoginView(TwoFactorLoginView):
    def get_success_url(self):
        # 先执行插件逻辑获取目标地址
        plugin_response = PluginManager.perform_action(
            "two_factor",
            self.request,
            email=self.request.user.email,
            password=self.request.POST.get("password"),
            token=self.request.POST.get("token"),
        )
        if isinstance(plugin_response, HttpResponseRedirect):
            return plugin_response.url
        # 自定义默认跳转地址,替代全局的LOGIN_REDIRECT_URL
        return reverse("login_success")
    
    def form_valid(self, form):
        # 执行父类的登录逻辑,但不返回其重定向响应
        super().form_valid(form)
        # 检查插件是否返回直接响应
        plugin_response = PluginManager.perform_action(
            "two_factor",
            self.request,
            email=self.request.user.email,
            password=form.cleaned_data.get("password"),
            token=self.request.POST.get("token"),
        )
        if isinstance(plugin_response, HttpResponse):
            return plugin_response
        # 否则跳转到自定义成功地址
        return HttpResponseRedirect(self.get_success_url())

方法2:完全手动控制登录与响应

跳过父类form_valid的重定向逻辑,手动完成登录并返回自定义响应:

class TwoFactor_LoginView(TwoFactorLoginView):
    def form_valid(self, form):
        # 手动执行登录(父类form_valid的核心逻辑就是调用form.save())
        form.save()
        # 执行插件逻辑
        plugin_response = PluginManager.perform_action(
            "two_factor",
            self.request,
            email=self.request.user.email,
            password=form.cleaned_data.get("password"),
            token=self.request.POST.get("token"),
        )
        if isinstance(plugin_response, HttpResponse):
            return plugin_response
        # 直接返回自定义HttpResponse,无需重定向
        return HttpResponse("登录成功,自定义响应内容")
        # 若需要重定向,可自行指定:
        # return HttpResponseRedirect(reverse("login_success"))

注意事项

  • form.save()已经包含了双因素认证的验证和用户登录逻辑,确保不要遗漏这一步,否则登录状态不会生效。
  • 如果插件依赖已登录的用户状态,必须在form.save()之后执行插件逻辑。

内容的提问来源于stack exchange,提问作者John Gardounis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 03:52:17