在Django中为Cookie添加Partitioned属性的优雅解决方案
问题背景
我在跨域环境下设置CSRF Cookie,视图代码如下:
@ensure_csrf_cookie @require_http_methods(['GET']) def set_csrf_token(request): return JsonResponse({'message': 'Set CSRF cookie'})
已在settings.py中配置跨域相关参数:
CSRF_COOKIE_SAMESITE = "None" CSRF_COOKIE_SECURE = True
但FireFox和Chrome浏览器要求这类标记为None; Secure的第三方/跨域Cookie添加Partitioned属性,而Django目前没有类似CSRF_COOKIE_PARTITIONED的直接配置项。补充说明:Partitioned属性目前为推荐而非强制要求,但Chrome和FireFox正逐步推进该属性成为必填项。
解决方案
方法1:自定义中间件全局处理
创建自定义中间件,在响应发送前自动为符合条件的CSRF Cookie添加Partitioned属性,适合全局生效场景:
- 在项目目录下创建
middleware.py文件,写入以下代码:
from django.conf import settings class CSRFPartitionedCookieMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): response = self.get_response(request) # 仅当CSRF Cookie配置为跨域模式时添加属性 if (settings.CSRF_COOKIE_SAMESITE == "None" and settings.CSRF_COOKIE_SECURE and settings.CSRF_COOKIE_NAME in response.cookies): response.cookies[settings.CSRF_COOKIE_NAME]['Partitioned'] = True return response
- 在
settings.py的MIDDLEWARE列表中注册该中间件(需放在CsrfViewMiddleware之后):
MIDDLEWARE = [ # ... 其他中间件 'django.middleware.csrf.CsrfViewMiddleware', '你的项目名.middleware.CSRFPartitionedCookieMiddleware', # ... 其他中间件 ]
方法2:视图内单独处理
如果仅需在特定视图中添加该属性,可直接在返回响应前修改Cookie:
from django.conf import settings from django.http import JsonResponse from django.views.decorators.http import require_http_methods from django.views.decorators.csrf import ensure_csrf_cookie @ensure_csrf_cookie @require_http_methods(['GET']) def set_csrf_token(request): response = JsonResponse({'message': 'Set CSRF cookie'}) if settings.CSRF_COOKIE_NAME in response.cookies: response.cookies[settings.CSRF_COOKIE_NAME]['Partitioned'] = True return response
方法3:等待官方原生支持
Django社区已针对该属性的原生支持展开讨论,后续版本大概率会新增CSRF_COOKIE_PARTITIONED配置项,可关注官方更新日志跟进。
内容的提问来源于stack exchange,提问作者8SIXSector
相关产品推荐
相关产品推荐

