10

我在 SO 上看到了很多关于此的内容,但没有什么可以解决我的问题。

问题:

启用 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.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        ...
    ]
    
  • 启用 cookie 的不同浏览器;

  • @ensure_csrf_cookie用;装饰我的视图

  • {% csrf_token %}在我的模板中设置;

  • 使用render具有正确请求上下文的快捷方式;

  • 在我的;中设置自定义CSRF_COOKIE_NAMECSRF_HEADER_NAMEsettings.py

  • 显式设置CSRF_COOKIE_SECURE = Falseand CSRF_COOKIE_HTTPONLY = False;

  • 显式设置CSRF_TRUSTED_ORIGINS设置;

  • 在开发和生产服务器上进行测试;

  • 即使request.META["CSRF_COOKIE_USED"] = True在我看来,正如有人建议的那样。

仍然一无所获。

标题:

如果我使用@csrf_exemptandprint(request.META)在我看来,很明显,自定义标头“X-CSRFToken”存在于请求中,并根据 Django 文档格式化,带有“HTTP_”前缀,用下划线替换连字符,全部大写:“HTTP_X_CSRFTOKEN”

更重要的是,它的值与 Django 设置的 cookie 匹配。

饼干:

奇怪的是,如果我尝试print(request.COOKIES)在我看来,在页面和表单加载中,我可以在那里看到“csrftoken” cookie,但AJAX 请求上的字典是空的。这可能是问题吗?

不顾一切地发现实际上是错误的。谢谢您阅读此篇。

4

1 回答 1

7

好的,那么问题很简单:

Fetch API 默认不发送凭据。根据MDN

Request 接口的 credentials 只读属性指示在跨域请求的情况下,用户代理是否应该从其他域发送 cookie。这类似于 XHR 的 withCredentials 标志,但具有三个可用值。

默认为omit,它从不发送 cookie。您只需要添加same-origin到您的fetch()函数参数:

fetch(formUrl, {
    ...
    credentials: 'same-origin',
    ...
})

你会很高兴去的:)

于 2016-03-08T14:26:05.010 回答