Django 1.9 AJAX form CSRF token 403 error - “CSRF cookie not set” [英] Django 1.9 AJAX form CSRF token 403 error - "CSRF cookie not set"
问题描述
问题:
在启用CSRF中间件的情况下,Django在AJAX表单请求中回应403,说明:
Cookie未设置。
按照文档,实现了一个JS功能,可设置自定义X-CSRFToken标题。
它按预期工作,从浏览器中获取csrftoken Cookie,并将其与AJAX请求一起发布:
x-csrftoken:1a0u7GCQG0wepZHQNThIXeYpMy2lZOf2
但回应仍为403。 >
尝试的解决方案:
我试过了在SO或web上找到的一切,具体为:
-
检查中间件是否已启用:
MIDDLEWARE_CLASSES = [
...
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
' django.contrib.auth.middleware.AuthenticationMiddleware',
...
]
-
启用Cookie的不同浏览器;
-
使用
@ensure_csrf_cookie
/ p> -
在我的范本中设定
{%csrf_token%}
; -
使用需要正确请求上下文的
render
快捷方式; -
settings.py
; 中的CSRF_COOKIE_NAME
和CSRF_HEADER_NAME
p> -
显式设置
CSRF_COOKIE_SECURE = False
和CSRF_COOKIE_HTTPONLY = False
; -
明确设置
CSRF_TRUSTED_ORIGINS
设置; -
测试开发和生产服务器;
-
甚至
request.META [CSRF_COOKIE_USED] = True
在我看来,有人建议。
b
$ b
标题:
如果我使用 @csrf_exempt
和 print(request.META)
在我看来,很明显,自定义标题X-CSRFToken到Django文档,带有HTTP_前缀,用下划线替换连字符,所有大写字母:HTTP_X_CSRFTOKEN。
奇怪的是,如果我尝试在我的视图中,在页面和表单加载我可以看到csrftoken cookie,但 c>打印(request.COOKIES) 对AJAX请求为空。可能是问题吗?
想要找到真正的错误。谢谢您阅读。
好的,问题很简单:
Fetch API默认不发送凭据。根据 MDN :
Request接口的凭据只读属性指示
用户代理是否应该从
中的其他域发送cookie cross -origin请求。这与XHR的
withCredentials标志类似,但具有三个可用值。
默认值为
,它从不发送cookie。您只需要向 fetch()
函数参数中添加 same-origin
:
fetch(formUrl,{
...
credentials:'same-origin',
...
})
你会很好的:)
I've seen a lot about this on SO, but nothing can fix my problem.
Problem:
With CSRF middleware enabled, Django responds with 403 on AJAX form request, stating:
"CSRF cookie not set."
Following the documentation, a JS functionality was implemented, that sets custom "X-CSRFToken" header.
It works as expected, gets "csrftoken" cookie from browser and posts it along with AJAX request:
x-csrftoken: 1a0u7GCQG0wepZHQNThIXeYpMy2lZOf2
But response is still 403.
Tried solutions:
I've tried everything I could find on SO or web, specifically:
Checking that middleware is enabled:
MIDDLEWARE_CLASSES = [ ... 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', ... ]
Different browsers with cookies enabled;
Decorating my view with
@ensure_csrf_cookie
;Setting
{% csrf_token %}
in my template;Using
render
shortcut which takes right request context;Setting custom
CSRF_COOKIE_NAME
andCSRF_HEADER_NAME
in mysettings.py
;Explicitly setting
CSRF_COOKIE_SECURE = False
andCSRF_COOKIE_HTTPONLY = False
;Explicitly setting
CSRF_TRUSTED_ORIGINS
setting;Testing on development and production server;
Even
request.META["CSRF_COOKIE_USED"] = True
in my view, as someone suggested.
And still got nothing.
Headers:
If I use @csrf_exempt
and print(request.META)
in my view, it's clear that custom header "X-CSRFToken" is present in request and formatted according to Django documentation, with "HTTP_" prefix, replaced hyphens with underscores, all uppercase: "HTTP_X_CSRFTOKEN".
Even more, it's value matches with cookie set by Django.
Cookies:
Strange thing is, if I try to print(request.COOKIES)
in my view, on page and form load I can see "csrftoken" cookie there, but dictionary is empty on AJAX request. Can it be the problem?
Desperate to find what is actually wrong. Thank you for reading this.
Ok, the issue is quite simple then:
Fetch API is not sending credentials by default. According to MDN:
The credentials read-only property of the Request interface indicates whether the user agent should send cookies from the other domain in the case of cross-origin requests. This is similar to XHR’s withCredentials flag, but with three available values.
Default is omit
, and it never sends cookies. You just need to add same-origin
to your fetch()
function arguments:
fetch(formUrl, {
...
credentials: 'same-origin',
...
})
And you'll be good to go : )
这篇关于Django 1.9 AJAX form CSRF token 403 error - “CSRF cookie not set”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!