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"

查看:612
本文介绍了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 and CSRF_HEADER_NAME in my settings.py;

  • Explicitly setting CSRF_COOKIE_SECURE = False and CSRF_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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆