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

如何修复Django中登录失败后CSRF TOKEN被表单数据覆盖的问题?

多租户项目登录表单异常:登录失败后CSRF Token与username字段被密码覆盖

我使用django-tenant和django-tenant-user构建多租户项目时遇到异常:登录尝试失败后,登录表单的CSRF Token与username字段会被密码数据覆盖。已尝试打印表单数据排查,但未找到根源——首次请求CSRF Token传递正常,后续请求中密码数据会被当作CSRF Token传递。

相关代码片段

View

def login_user(request):
    if request.user.is_authenticated:
        return redirect('core:index')
    if request.method != 'POST':
        form = LoginForm()
        return render(request, 'core/login.html', {'form': form})
    form = LoginForm(request.POST)
    if not form.is_valid():
        context = {"form": form}
        if not form.errors:
            messages.error(request, 'Invalid username or password')
        return render(request, 'core/login.html', context)
    user = authenticate(request, username=form.cleaned_data['username'], password=form.cleaned_data['password'])
    if user is None:
        messages.error(request, 'Invalid username or password.')
        return render(request, 'core/login.html', {'form': form})
    messages.success(request, 'Login successful')
    login(request, user)
    return redirect('core:index')

Form

class LoginForm(forms.Form):
    username = forms.CharField(min_length=4, max_length=150)
    password = forms.CharField(min_length=4, max_length=128, widget=forms.PasswordInput)

Template

{% extends "_base.html" %}

{% block title %}
  <title>TalwaPro HR Admin - Login </title>
{% endblock title %}

{% block content %}

{% load tailwind_filters %}

<div class="flex h-screen items-center justify-center">
  <div class="card w-[90%] bg-base-200 shadow-xl justify-center md:w-[65%] lg:w-[40%]">
    {% if messages %}
      <div class="toast toast-top toast-start">
        <div class="alert alert-error">
          {% for message in messages %}
            {{ message }}
          {% endfor %}
        </div>
      </div>
    {% endif %}
    <div class="card-body">
      <h2 class="card-title text-accent justify-center">Sign In</h2>
      <form class="mt-4" action="/login/" method="POST">
        {% csrf_token %}
        <label class="input input-bordered flex items-center gap-2 {% if form.username.errors %} border-error {% endif %}">
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="w-4 h-4 opacity-70"><path d="M8 8a3 3 0 1 0 0-6 3 3 0 0 0 0 6ZM12.735 14c.618 0 1.093-.561.872-1.139a6.002 6.002"></path></svg>
          <input type="text" class="grow" name="username" value="{% if form.username.value %} {{form.username.value}} {% endif %}" placeholder="Username" required />
        </label>
        <div class="text-error">
          {% if form %}
            {{ form.username.errors }}
          {% endif %}
        </div>
        <label class="input input-bordered flex items-center gap-2 mt-4 {% if form.password.errors %} border-error {% endif %}">
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="w-4 h-4 opacity-70"><path fill-rule="evenodd" d="M14 6a4 4 0 0 1-4.899 3.899l-1.955 1.955a.5.5 0 0 1-.353.146H5v1"></path></svg>
          <input type="password" class="grow" name="password" placeholder="Password" required />
        </label>
        <div class="text-error">
          {% if form %}
            {{ form.password.errors }}
          {% endif %}
        </div>
      <div class="card-actions justify-center mt-4">
        <button class="btn btn-primary" type="submit">Sign In</button>
      </div>
      </form>
    </div>

  </div>
</div>
{% endblock %}

问题根源与解决方案

问题根源

模板中的<svg>标签未正确闭合,导致HTML结构解析错乱。浏览器在处理未闭合标签时,会错误地将后续表单元素(包括CSRF Token隐藏字段)纳入SVG标签范围,进而引发表单数据提交时的字段值覆盖问题。

解决方案

  1. 修复未闭合的SVG标签
    给每个<svg>标签添加闭合的</svg>标签,确保HTML结构完整。修正后的示例:

    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="w-4 h-4 opacity-70">
      <path d="M8 8a3 3 0 1 0 0-6 3 3 0 0 0 0 6ZM12.735 14c.618 0 1.093-.561.872-1.139a6.002 6.002"></path>
    </svg>
    
  2. 改用Django表单内置渲染方式
    避免手动编写表单输入字段,使用Django表单的字段渲染语法,结合tailwind_filters简化样式处理,同时避免手动HTML的结构错误:

    {{ form.username|add_class:"grow" }}
    {{ form.password|add_class:"grow" }}
    
  3. 验证HTML结构
    修复后通过浏览器开发者工具检查页面HTML结构,确认所有标签闭合正常,CSRF Token隐藏字段位于表单内正确位置。

内容的提问来源于stack exchange,提问作者Maxwell D. Dorliea

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 03:20:55