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

为何Set-Cookie头中无CSRF Token?Django DRF接口问题咨询

问题分析与解决方案

我来帮你拆解下这个问题——你遇到的情况其实和Django及DRF的CSRF防护机制默认逻辑有关,之前我也碰到过类似的坑。

核心原因

Django的CSRF中间件默认只会在返回HTML内容的GET请求中自动设置Set-Cookie头(比如Django自带的模板页面),而DRF的APIView返回的是JSON格式响应,默认不会主动触发CSRF Cookie的生成和设置。哪怕Postman里之前存过CSRF Cookie,一旦过期或被清除,后续的GET请求就没法再获取新的Cookie了。

另外,DRF的SessionAuthentication虽然依赖CSRF验证,但它不会在未登录的GET请求中自动生成CSRF Cookie,只有当用户通过session登录后,相关逻辑才会触发。

解决办法

1. 在GET方法中手动触发CSRF Cookie生成

你可以在get方法里调用Django提供的get_token()函数,这个函数会自动生成CSRF Token并将其添加到响应的Set-Cookie头中。修改你的代码如下:

from django.middleware.csrf import get_token
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status

class HelloView(APIView):
    def get(self, request):
        # 手动触发CSRF Cookie生成
        get_token(request)
        clients = client.objects.all()
        serializer = ClientSerializerAPIView(clients, many=True)
        return Response(serializer.data)
    
    def post(self, request):
        serializer = ClientSerializerAPIView(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

注意:我把你post方法里的HTTP_404_NOT_FOUND改成了HTTP_400_BAD_REQUEST,因为参数验证失败应该返回400(请求错误)而不是404(资源不存在),这是更规范的REST接口做法。

2. 确认CSRF中间件已启用

检查你的settings.py文件,确保MIDDLEWARE列表中包含'django.middleware.csrf.CsrfViewMiddleware',这是CSRF Cookie生成的基础:

MIDDLEWARE = [
    # 其他中间件...
    'django.middleware.csrf.CsrfViewMiddleware',
    # 其他中间件...
]

3. 测试验证

修改代码后,用Postman重新发送GET请求,你就能在响应头里看到Set-Cookie字段,里面包含新的CSRF Token了。之后发送POST请求时,记得把这个Token放到X-CSRFToken请求头里,或者作为表单数据提交,这样就能通过DRF的CSRF验证了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:09:22