Django 1.9 AJAX表单CSRF令牌403错误 - “未设置CSRF cookie”

时间:2016-03-08 13:09:33

标签: ajax django cookies csrf fetch-api

我在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快捷方式获取正确的请求上下文;

  • CSRF_COOKIE_NAME;

  • 中设置自定义CSRF_HEADER_NAMEsettings.py
  • 明确设置CSRF_COOKIE_SECURE = FalseCSRF_COOKIE_HTTPONLY = False;

  • 明确设置CSRF_TRUSTED_ORIGINS设置;

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

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

仍然一无所获。

接头

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

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

饼干:

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

迫切希望找到真正的错误。感谢您阅读本文。

1 个答案:

答案 0 :(得分:7)

好的,问题很简单:

默认情况下,Fetch API不会发送凭据。根据{{​​3}}:

  

Request接口的凭证只读属性表示   用户代理是否应该从其他域发送cookie   跨域请求的情况。这与XHR相似   withCredentials标志,但有三个可用值。

默认为omit,它永远不会发送Cookie。您只需要将same-origin添加到fetch()函数参数:

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

你会很高兴:)