【问题标题】:Django csrf ajax fails only on productionDjango csrf ajax 仅在生产中失败
【发布时间】:2016-01-04 18:38:21
【问题描述】:

据我所知,我已将所有内容设置正确,并且在开发中有效:

我已包含以下代码:

function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie != '') {
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = jQuery.trim(cookies[i]);
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) == (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}
var csrftoken = getCookie('csrftoken');

function csrfSafeMethod(method) {
    // these HTTP methods do not require CSRF protection
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
    beforeSend: function(xhr, settings) {
        if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
            xhr.setRequestHeader("X-CSRFToken", csrftoken);
        }
    }
});

这可能会在开发中起作用但在生产中不起作用的原因是什么?

【问题讨论】:

  • 您是否确认此代码确实包含在生产中?你能在开发工具中看到它吗?部署静态文件后,我很多时候忘记运行collectstatic
  • 是的,它肯定包括在内。我刚刚在控制台中输入了getCookie('csrftoken'),它返回了null,这是怎么回事?
  • 当你说它失败时,你得到的确切失败是什么?调用未触发,服务器返回错误等?
  • 当你不发送 csrftoken CSRF verification failed. Request aborted. 我刚刚在控制台中输入 document.cookie.indexOf('csrftoken') 并返回 -1 时,我收到了你收到的消息不存在,是什么原因造成的?
  • 使用浏览器的开发者工具或curl -i再次检查cookie是否正在发送。例如,如果 CSRF_COOKIE_HTTPONLY = True,那么 JavaScript 将无法读取 cookie,并且不会出现在 document.cookie 中。

标签: ajax django csrf


【解决方案1】:

一个可能的原因是您的生产设置中有 CSRF_COOKIE_SECURE = True。这将仅通过 HTTPS 连接发送 cookie。如果您已启用此功能,但希望视图在没有 CSRF 令牌的情况下处理 POST 请求,请使用 csrf_exempt 装饰视图。

编辑:还要检查是否启用了 SESSION_COOKIE_SECURE。如果设置为 True,就会遇到这个问题。

我遇到了类似的问题,并通过将登录用户(Django 管理页面)的 url 移动到仅通过 HTTPS 提供服务来解决它,从而消除了对后一种设置的需要。我仍然保留 CSRF_COOKIE_SECURE = True 和处理 POST 请求 (set_language) 所需的单个 URL,并用 @csrf_exempt 包裹,以便它可以绕过此设置。这意味着任何需要处理匿名会话表单的视图也需要进行类似的修饰。

目前一切似乎都运行良好,但我仍在研究是否对我的配置有任何其他安全隐患。此外,可能有更好的方法来处理这个问题。在那之前,我可以接受这种方法。 HTH。

【讨论】:

【解决方案2】:

在我的情况下,以下解决了问题:

@ensure_csrf_cookie
def your_view(request)

根据文档,如果没有包含 {% csrf_token %} 的表单,则可能无法设置 csrf cookie。

https://docs.djangoproject.com/en/1.10/ref/csrf/#django.views.decorators.csrf.ensure_csrf_cookie

【讨论】:

    猜你喜欢
    • 2017-08-17
    • 2011-09-17
    • 2012-01-10
    • 2020-03-24
    • 2011-09-28
    • 2011-09-21
    • 2017-05-11
    • 2015-10-15
    • 2012-12-27
    相关资源
    最近更新 更多