Django中已添加{% csrf_token %}仍提示CSRF Token Missing求助
Django登录页面CSRF验证失败问题排查与修复
问题分析
你的代码存在几个关键问题导致CSRF验证失败:
- 视图未传递request上下文:
LogIn视图使用template.render()时未传入request对象,Django无法生成有效的CSRF token。 - 重复添加CSRF token标签:模板中多次添加
{% csrf_token %},属于冗余操作,正确做法是在<form>标签内仅添加一次。 - 表单提交逻辑错误:提交按钮设置了
href="/verify",会导致点击时直接跳转而非通过表单POST请求提交,同时表单action属性未正确指向处理视图。 - 表单输入无name属性:邮箱和密码输入框缺少
name属性,即使CSRF验证通过,后端也无法获取提交的数据。
修复方案
1. 修正views.py代码
使用Django内置的render函数,它会自动传递request上下文,确保CSRF token正确生成:
from django.shortcuts import render, redirect def LogIn(request): # 使用render函数替代手动加载模板,自动传递request上下文 return render(request, 'login.html') def verify(request): # 处理POST请求逻辑 if request.method == 'POST': email = request.POST.get('email') password = request.POST.get('password') # 后续登录验证逻辑... return redirect('login') # 示例:验证后跳转回登录页
2. 修正模板login.html代码
- 移除冗余的
{% csrf_token %},仅保留一个在<form>内 - 去掉提交按钮的
href属性,设置表单action指向verify视图 - 为输入框添加
name属性,确保后端能获取数据
<!doctype html> <html lang="en"> <head> <!-- Required meta tags --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <!-- Bootstrap CSS --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"> <title>Login Page</title> </head> <body> <h1>Login Page</h1> <!-- 设置表单action指向verify视图 --> <form action="/verify" method="post"> {% csrf_token %} <!-- 仅保留一个CSRF token标签 --> <div class="form-group"> <label for="exampleInputEmail1">Email address</label> <!-- 添加name属性,用于后端获取数据 --> <input style="max-width: 50%;" type="email" name="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="Enter email"> <small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small> </div> <div class="form-group"> <label for="exampleInputPassword1">Password</label> <!-- 添加name属性,用于后端获取数据 --> <input style="max-width: 50%;" type="password" name="password" class="form-control" id="exampleInputPassword1" placeholder="Password"> </div> <!-- 移除href属性,仅保留submit类型按钮 --> <button style="margin-top: 15px; margin-left: 25%; padding-right: 30px; padding-left: 30px;" type="submit" class="btn btn-primary">Submit</button> </form> <!-- 注册按钮改为type="button",避免触发表单提交 --> <button style="margin-top: 30px; margin-left: 25%; padding-right: 30px; padding-left: 30px;" type="button" class="btn btn-primary">Sign Up</button> <!-- Optional JavaScript --> <!-- jQuery first, then Popper.js, then Bootstrap JS --> <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/popper.js@1.12.9/dist/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script> </body> </html>
3. 补充路由配置(urls.py)
确保在项目的urls.py中配置LogIn和verify的路由:
from django.urls import path from . import views urlpatterns = [ path('', views.LogIn, name='login'), path('verify/', views.verify, name='verify'), ]
关键说明
- Django的CSRF防护依赖request上下文和正确的token传递,必须确保视图渲染模板时传入request对象。
- 表单提交必须通过POST请求,且
{% csrf_token %}生成的隐藏输入框必须包含在表单内。 - 输入框的
name属性是后端获取数据的关键,不可遗漏。
内容的提问来源于stack exchange,提问作者Milosz Placzek
相关产品推荐
相关产品推荐

