Django 1.9 AJAX形式CSRF令牌403错误 - “CSRF cookie not set” [英] Django 1.9 AJAX form CSRF token 403 error - "CSRF cookie not set"
问题描述
问题:
启用CSRF中间件后,Django以AJAX格式请求403回复,说明:
CSRF cookie未设置。
按照文档,实现了一个JS功能,设置自定义X-CSRFToken标题。
它按预期工作,从浏览器获取csrftoken cookie,并发布AJAX请求:
x-csrftoken:1a0u7GCQG0wepZHQNThIXeYpMy2lZOf2
但是回复仍然是403。 >
试用的解决方案:
我尝试过在SO或网络上找到的一切,具体地:
-
检查中间件是否启用:
MIDDLEWARE_CLASSES = [
...
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf .crfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
...
]
-
启用Cookie的不同浏览器;
-
使用
@ensure_csrf_cookie装饰我的视图
; -
在我的模板中设置
{%csrf_token%}
/ p> -
使用
render
快捷方式,它具有正确的请求上下文; -
在我的
settings.py中设置自定义
CSRF_COOKIE_NAME
和CSRF_HEADER_NAME
/ code>; -
明确设置
CSRF_COOKIE_SECURE = False
和CSRF_COOKIE_HTTPONLY = False
; -
明确设置
CSRF_TRUSTED_ORIGINS
设置; -
开发和生产服务器测试;
-
即使
request.META [CSRF_COOKIE_USED] = True
在我看来,正如有人建议的。
仍然没有任何东西。
标题: / p>
如果我使用 @csrf_exempt
和 print(request.META)
在我看来,很明显,自定义标头X-CSRFToken存在于请求中,并根据Django文档格式化,使用HTTP_前缀,用下划线替换连字符,全部大写:HTTP_X_CSRFTOKEN。
更多的是,它与Django设置的cookie匹配。
Cookie:
奇怪的是,如果我尝试 print(request.COOKIES)
在我看来,页面和表单加载我可以看到csrftoken cookie,但AJAX请求上的字典为空。可能是问题吗?
绝望找到实际错误。谢谢你阅读。
好的,问题很简单:
默认情况下,Fetch API不发送凭据。根据 MDN :
请求界面的凭据只读属性表示
用户代理是否从
中的另一个域发送cookie,交叉-origin请求。这与XHR的
withCredentials标志类似,但有三个可用值。
默认值为省略
,它不会发送cookie。您只需在 fetch()
函数参数中添加 same-origin
:
fetch(formUrl,{
...
凭证:'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形式CSRF令牌403错误 - “CSRF cookie not set”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!