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

Django同页面多AJAX请求下CSRF_token无效问题解决方案咨询

解决OTP登录流程中CSRF Token无效问题

核心认知纠正

Django的CSRF Token默认并非一次性有效,只要会话未过期,同一个Token可以复用多次。你遇到的问题本质是请求中Token的携带方式错误,而非Token本身失效。

具体解决方案

1. 修复表单的CSRF Token存储方式

在HTML表单中添加Django官方推荐的{% csrf_token %}模板标签,自动生成隐藏的Token输入字段,替代硬编码的模板变量:

<form id="loginForm" method="post" action="send_otp">
  {% csrf_token %} <!-- 新增:自动生成隐藏的CSRF Token输入框 -->
  <div class="col-12">
    <label class="text-16 lh-1 fw-500 text-dark-1 mb-10">Email</label>
    <input id="email" type="text" name="email" placeholder="Email">
  </div>
  <div class="col-12">
    <label class="text-16 lh-1 fw-500 text-dark-1 mb-10">Password</label>
    <input id="password" type="password" name="password" placeholder="Password">
  </div>
  <div id="otp_field" class="col-12">
  </div>
  <div class="col-12">
    <button type="submit" name="submit" id="send_otp" class="button -md -green-1 text-dark-1 fw-500 w-1/1">Login</button>
  </div>
</form>

2. 修改AJAX请求逻辑,动态获取并携带Token

移除JS中硬编码的{{ csrf_token }},改为动态读取表单中的隐藏Token值,同时区分第一次提交(发送OTP)和第二次提交(验证OTP)的接口:

$("#loginForm").submit(function(event) {
  event.preventDefault();
  var $form = $(this);
  var url = $form.attr('action');
  var postData = {
    "csrfmiddlewaretoken": $('input[name="csrfmiddlewaretoken"]').val(), // 动态读取Token
    "email": $('#email').val(),
    "pass": $('#password').val()
  };

  // 判断是否需要提交OTP验证请求
  if ($('#otp').length > 0) {
    url = "verify_otp"; // 替换为你的OTP验证接口地址
    postData["otp"] = $('#otp').val();
  }

  var posting = $.post(url, postData);

  posting.done(function(data) {
    if (!$('#otp').length) {
      // 第一次提交成功,显示OTP输入框并更新按钮状态
      $('#email').attr('disabled','disabled');
      $('#password').attr('disabled','disabled');
      $('#otp_field').append('<label class="text-16 lh-1 fw-500 text-dark-1 mb-10">Enter OTP</label><input id="otp" type="text" name="otp" placeholder="Enter OTP">');
      $('#send_otp').text('Verify OTP');
    } else {
      // OTP验证成功,跳转到目标页面
      window.location.href = "/dashboard"; // 替换为你的登录后页面
    }
  });

  posting.fail(function(xhr) {
    // 错误提示示例
    alert(xhr.responseJSON?.message || "请求失败,请重试");
  });
});

3. 额外配置检查

  • 确保Django settings.py中CSRF_COOKIE_HTTPONLY = False(默认值),否则JS无法读取Token字段;
  • 若后台配置了CSRF_USE_SESSIONS = True,只要用户会话有效,Token即可持续复用;
  • 如果后台会在响应中返回新的Token(如X-CSRFToken响应头),可在posting.done中更新表单Token:
    var newToken = xhr.getResponseHeader('X-CSRFToken');
    if (newToken) $('input[name="csrfmiddlewaretoken"]').val(newToken);
    

内容的提问来源于stack exchange,提问作者Yogesh Yadav

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 07:54:19