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
相关产品推荐
相关产品推荐

