Django 1.9 AJAX 表单 CSRF 令牌 403 错误 - “未设置 CSRF cookie”
Posted
技术标签:
【中文标题】Django 1.9 AJAX 表单 CSRF 令牌 403 错误 - “未设置 CSRF cookie”【英文标题】:Django 1.9 AJAX form CSRF token 403 error - "CSRF cookie not set" 【发布时间】:2016-06-22 10:53:19 【问题描述】:我在 SO 上看到了很多关于此的内容,但没有什么可以解决我的问题。
问题:
启用 CSRF 中间件后,Django 在 AJAX 表单请求中以 403 响应,说明:
“未设置 CSRF cookie。”
在documentation之后,实现了一个JS功能,它设置了自定义“X-CSRFToken”标头。
它按预期工作,从浏览器获取 "csrftoken" cookie 并将其与 AJAX 请求一起发布:
x-csrftoken: 1a0u7GCQG0wepZHQNThIXeYpMy2lZOf2
但响应仍然是 403。
尝试过的解决方案:
我已经尝试了所有可以在 SO 或网络上找到的东西,特别是:
检查中间件是否启用:
MIDDLEWARE_CLASSES = [
...
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
...
]
启用 cookie 的不同浏览器;
用@ensure_csrf_cookie
装饰我的视图;
在我的模板中设置% csrf_token %
;
使用render
快捷方式获取正确的请求上下文;
在我的settings.py
中设置自定义CSRF_COOKIE_NAME
和CSRF_HEADER_NAME
;
显式设置CSRF_COOKIE_SECURE = False
和CSRF_COOKIE_HTTPONLY = False
;
显式设置CSRF_TRUSTED_ORIGINS
设置;
在开发和生产服务器上测试;
在我看来,即使是 request.META["CSRF_COOKIE_USED"] = True
,正如有人建议的那样。
还是一无所获。
标题:
如果我在我看来使用 @csrf_exempt
和 print(request.META)
,很明显自定义标头 "X-CSRFToken" 存在于请求中,并根据 Django 文档格式化,带有“HTTP_”前缀, 用下划线替换连字符,全部大写:"HTTP_X_CSRFTOKEN"。
更重要的是,它的值与 Django 设置的 cookie 匹配。
Cookie:
奇怪的是,如果我尝试 print(request.COOKIES)
在我看来,在页面和表单加载我可以看到 "csrftoken" cookie 那里,但字典是 AJAX 请求空。会不会是问题?
急于找出真正的问题所在。感谢您阅读本文。
【问题讨论】:
你能展示你的实际视图和javascript吗? 你用什么来发送 AJAX 请求? jQuery? @Smile0ff:获取 API。 大声笑,阅读您的调试过程有点不可思议,因为我按照基本完全相同的顺序执行了完全相同的步骤 :) 【参考方案1】:好的,那么问题就很简单了:
Fetch API 默认不发送凭据。根据MDN:
Request接口的credentials只读属性表示 用户代理是否应该从其他域发送 cookie 跨域请求的情况。这类似于 XHR 的 withCredentials 标志,但具有三个可用值。
默认是omit
,它从不发送cookies。您只需将same-origin
添加到您的fetch()
函数参数中:
fetch(formUrl,
...
credentials: 'same-origin',
...
)
你会很高兴的:)
【讨论】:
以上是关于Django 1.9 AJAX 表单 CSRF 令牌 403 错误 - “未设置 CSRF cookie”的主要内容,如果未能解决你的问题,请参考以下文章
django:csrf_token 用于单个页面上的多个表单和 ajax 请求
Django - 在同一个模板(ajax 和表单)中处理多个 CSRF 令牌禁止(CSRF 令牌丢失或不正确。)