Django登录后刷新报CSRF verification failed错误如何解决
问题根因
你触发了Django CSRF校验失败的典型场景,核心错误出在视图函数的登录成功返回逻辑:
- 你在POST类型的登录请求校验通过后,直接用
render返回了首页内容,没有遵循POST→重定向→GET的PRG开发规范。此时浏览器地址栏仍然停留在登录接口路径,用户刷新页面时浏览器会自动重发之前的登录POST请求,而登录成功后Django会自动轮换session,旧请求携带的CSRF Token已经和新session不匹配,直接触发校验失败。 - 表单中额外添加的id为csrf_token的隐藏input属于冗余代码,不过这不是本次报错的核心原因。
修复方案
第一步:修改signin视图逻辑
登录成功后不要直接渲染页面,改为重定向到首页路由,Django的messages框架会自动缓存提示信息,重定向后仍然可以正常显示:
def signin(request): if request.method=="POST": username = request.POST.get('username') password = request.POST.get('password') user = authenticate(username=username,password=password) if user is not None: login(request,user) messages.success(request,"Logged in Successfully!") # 把这里的render改成重定向到首页 return redirect('index') else: messages.error(request,"Bad Credentials") return redirect('index') return render(request,'authtest/signin.html')
第二步:清理表单冗余代码(可选)
表单中{% csrf_token %}模板标签已经会自动生成合法的CSRF Token隐藏字段,你额外添加的隐藏input没有作用,可以直接删除:
<form action="{% url 'signin' %}" method="POST"> {% csrf_token %} <label for="username">用户名</label> <input type="text" name="username" id="username" required> <label for="password">密码</label> <input type="password" name="password" id="password" required> <button type="submit">登录</button> </form>
修复后登录成功会自动跳转到首页,此时浏览器地址栏是首页路径,刷新页面只会发送GET请求获取首页内容,不会再触发CSRF校验错误。
内容的提问来源于stack exchange,提问作者Kamesh Kotwani
相关产品推荐
相关产品推荐

