【问题标题】:django no csrftoken in cookiedjango 在 cookie 中没有 csrftoken
【发布时间】:2012-11-04 22:42:18
【问题描述】:

我正在测试发出 POST ajax 请求,但由于没有 csrftoken,我得到了 403。我跟着文档,但是还是不行,发现名为csrftoken的cookie是empty,意思是$.cookie("csrftoken")return null

谁能告诉我原因以及如何将csrftoken 设置到cookie 中?

【问题讨论】:

  • 之前有过类似的问题,与 csrf_protect 装饰器有关。如果您从一个页面发布到另一个 url(例如 ajax)并且如果您使用的是 @csrf_protect 装饰器等,请确保两者查看您发布数据的来源以及接收发布数据的 url 以拥有此装饰器。
  • 你的观点,你的模板表单?

标签: django ajax csrf-token


【解决方案1】:

我认为您应该提供如何在 HTML/JS 代码和中间件设置中获取 csrf 令牌的代码。

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

我遇到了类似的问题,在 python 代码中我使用request.META.get('CSRF_COOKIE') 来获取令牌。

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

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

1.你可以强制Django设置CSRF Coo​​kie:

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

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

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      问题出在我的 Django 配置中,我注释了以下行并且它有效:

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

      【讨论】:

      • 是的,http-only cookie 无法通过浏览器中的 javascript 访问。
      • @o_c 你在哪里评论?
      【解决方案4】:

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

      Ajax 请求不再因403 Forbidden 错误而被拒绝,并且被正确执行(前提是在 AJAX 标头中设置了 csrf_token)。

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

      【讨论】:

      • 如何在前端获取csrftoken
      【解决方案5】:

      首先,如果您正在设计应用程序,最好在标头或 POST 请求中使用 csrf Token,而不是在 cookie 中,因为:

      • 所有表单都必须将值动态添加到其 HTML 中。任何 AJAX POST 还必须包含该值。
      • 将为每个请求提交 cookie(即所有 GET 图片、CSS、JS等不参与CSRF流程) 增加请求大小。

      如果你想在 django 中强制使用 cookie,你总是可以:

      request.META["CSRF_COOKIE_USED"] = True
      

      如果您没有在任何地方使用 {% csrf_token %} 在您的项目中。根据 [documentation][1],您不需要做任何其他事情,只需编写一个简单的 javascript 代码即可。其实这不是真的。您必须在每个视图中放置"request.META['CSRF_COOKIE_USED'] = True" 行(或编写适当的装饰器)。

      【讨论】:

      • 您是否考虑过对文档提出拉取请求以包含此内容?
      猜你喜欢
      • 1970-01-01
      • 2017-12-04
      • 1970-01-01
      • 2018-01-04
      • 1970-01-01
      • 1970-01-01
      • 2015-08-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多