2012-11-16 89 views
11

我测试做一个POST Ajax请求Django的没有csrftoken在饼干

我得到了403,因为没有csrftoken

我跟着文档的,它仍然无法正常工作。

,我发现了一个名为csrftoken cookie是

这意味着$ .cookie( “csrftoken”)返回null

有人可以告诉我的理由!

如何将csrftoken设置为cookie

THX !!

+0

之前有一个类似的问题,是用csrf_protect修饰器。如果你从一个页面发布到另一个url(例如ajax),并且如果你使用@csrf_protect修饰器等,请确保你发布的视图数据和网址接收发布的数据有这个装饰。 – sidarcy

+1

您的看法,您的模板形式? –

回答

15

我认为你应该提供代码如何在你的HTML/JS代码和你的中间件设置中获得csrf标记。

首先您应该检查是否打开了django.middleware.csrf.CsrfViewMiddleware

我有一个类似的问题,当在Python代码中我使用request.META.get('CSRF_COOKIE')来获取令牌。

当您在模板中使用此标记 - {% csrf_token %} Django注意到该标记已呈现并将CsrfViewMiddleware.process_response中的Cookie设置为。如果以其他方式获得令牌值,Django将会错过这个标志。所以它会生成一个令牌,但不会设置相应的cookie。

我在代码中有2个解决方法。您应该将它添加到您用于使用JS代码生成模板的视图中。

您可以强制Django的设置CSRF的Cookie:

# Force updating CSRF cookie 
request.META["CSRF_COOKIE_USED"] = True 

2. Django的自动设置CSRF_COOKIE_USED如果你调用get_token

from django.middleware.csrf import get_token 
# don't use direct access to request.META.get('CSRF_COOKIE') 
# in this case django will NOT send a CSRF cookie. Use get_token function 
csrf_token = get_token(request) 

这个解决方案中的每一个应该分开工作。我建议使用get_token

+0

我真的很抱歉,我忘了这个。谢谢您的回答。 –

13

您可能想要使用ensure_csrf_cookie视图装饰器(自从Django 1.4开始提供)。即使您没有使用{{ csrf_token }}模板标签,这也会设置csrftoken cookie。

+1

这个方法适合我! – Max

3

我有同样的问题($ .cookie('csrftoken')返回'undefined')。

的问题是在我的Django的配置,我评论如下行,它的工作原理:

#CSRF_COOKIE_HTTPONLY = True # Prevent client-side JavaScript access to the CSRF cookie 
+0

是的,http-only cookie无法在浏览器中通过javascript访问。 –

2

扩展在o_c's answer:通过注释CSRF_COOKIE_HTTPONLY线,csrf_token值不再“未定义”(在Firefox萤火)并显示为“真实”值,例如'qGuPe2Q7 ...等'。

Ajax请求不再被拒绝,并且403 Forbidden错误被正确执行(假设csrf_token设置在AJAX头中)。

 $.ajaxSetup({ 
      beforeSend: function(xhr, settings) { 
       if (!csrfSafeMethod(settings.type) && !this.crossDomain) { 
       xhr.setRequestHeader("X-CSRFToken", csrftoken); 
       } 
      } 
     }); 
1

首先,如果你正在设计的应用程序,它始终是更好地在页眉或POST请求,而不是在一个cookie CSRF使用令牌,因为:

  • 所有表格必须动态地将其值添加到其HTML中。任何AJAX POSTs还必须包含该值。
  • 该cookie将针对每个请求提交(即所有GET请求的大小为 图片,CSS,JS等,不涉及CSRF进程) 。

如果要强制在Django饼干的使用,你总是可以:

request.META["CSRF_COOKIE_USED"] = True 
在您的项目

,如果你不使用{%csrf_token%}任何地方。根据[文档] [1],您不需要执行其他任何操作,但可以编写一个简单的JavaScript代码。事实上并非如此。你必须在每个视图中放入"request.META['CSRF_COOKIE_USED'] = True"行(或者编写适当的装饰器)。