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

Django视图中如何正确实现CSRF验证?解决403禁止访问问题

问题解答

核心原因

你出现403错误的根本问题并非CsrfViewMiddleware和@csrf_protect冲突——默认项目都会启用CsrfViewMiddleware全局保护,@csrf_protect仅用于给被全局排除的视图单独添加保护,二者共存不会直接引发错误。真正的问题是你硬编码的表单里没有包含CSRF令牌字段:只要开启了CSRF保护(无论全局中间件还是装饰器),POST请求必须携带合法的CSRF令牌才能通过验证。之前用模板时添加了{% csrf_token %},自动生成了令牌字段,所以功能正常。

关于你的疑问:可以在视图内处理CSRF验证,不一定必须用模板

只要能确保POST请求携带CSRF令牌,不用模板也可行。下面提供两种解决方案:

方案1:手动在视图生成CSRF令牌并插入表单

先导入CSRF令牌生成函数,再在返回表单时将令牌作为隐藏字段插入:

from django.middleware.csrf import get_token
from django.shortcuts import redirect, reverse
from django.http import HttpResponse
from .models import Group

@csrf_protect  # 若已启用全局CsrfViewMiddleware,该装饰器可省略
def create_group(request):
    if request.method == "POST":
        Group.objects.create(**{key: request.POST[key] for key in request.POST})
        return redirect(reverse("groups:groups"))
    
    # 生成当前请求的CSRF令牌
    csrf_token = get_token(request)
    # 将令牌字段插入表单末尾
    form_html = create_group_form.replace(
        "</form>",
        f'<input type="hidden" name="csrfmiddlewaretoken" value="{csrf_token}"></form>'
    )
    return HttpResponse(form_html)

方案2:改用Django模板(推荐)

这是更规范的做法,将表单内容放到模板文件(如create_group_form.html)中:

<form method="POST">
  {% csrf_token %}
  <label for="course">Course:</label><br>
  <input type="text" id="course" name="course"><br><br>
  <!-- 其余表单字段保持不变 -->
  <input type="submit" value="Submit">
</form>

修改视图,用render返回模板:

from django.shortcuts import render, redirect, reverse
from .models import Group

# 全局已启用CsrfViewMiddleware时,无需@csrf_protect
def create_group(request):
    if request.method == "POST":
        Group.objects.create(**{key: request.POST[key] for key in request.POST})
        return redirect(reverse("groups:groups"))
    return render(request, "create_group_form.html")

额外说明

如果你的settings.py中已经启用了django.middleware.csrf.CsrfViewMiddleware(默认开启),@csrf_protect装饰器属于冗余配置,去掉它不影响CSRF保护效果,只要表单包含令牌字段即可。

内容的提问来源于stack exchange,提问作者Алексей Василенко

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 22:18:30