【问题标题】:Django ajax 403 because of httponly cookieDjango ajax 403 因为 httponly cookie
【发布时间】:2017-06-27 17:22:30
【问题描述】:

我对 Django 中的 CSRF 有一个奇怪的问题。以下是相关部分:

在我的 javascript 文件中:

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));
}

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

$.post('/api/jpush',
  $.param({'recipients': recipients, 'message': message, 'url': url,
           'url_title': url_title, 'priority': priority,
             'csrftoken': getCookie('csrftoken')}),
...

那么我认为:

def push(request):    
  return render(request, 'api/push.html')    

def jpush(request):
  tmplData = {'result': False}

  if not request.POST:
    return HttpResponseBadRequest(request)
  elif request.POST.viewkeys() & {'recipients', 'message', 'priority'}:
    tmplData = { 'results': send(request.POST) }

  return JsonResponse(tmplData)

....

在我的模板中:

<form id="push" class="form-horizontal" action="" method="post">{% csrf_token %}

但是,当我使用 ajax 发布时,我得到一个 403,并且 firebug 显示 crsftoken 值为 null 并且 csrftoken cookie 为 httpOnly。我在settings.py 中将CSRF_COOKIE_HTTPONLY 设置为False,所以我不明白为什么cookie 被强制为httpOnly。我正在使用 Django 1.10。

谢谢

【问题讨论】:

  • 在您设置CSRF_COOKIE_HTTPONLY = False 之前,您是否有唯一的http only cookie。尝试清除您的 cookie,然后重试。
  • 是的,我在我的settings.py 文件中设置了它,并且我已经清除了几次cookie,但根据萤火虫它总是以httponly 的形式返回。我尝试使用 document.cookie 查看 cookie,但它也没有显示在那里,这证实了萤火虫正在显示的内容。
  • 确保您已重置服务器并在更改设置后清除 cookie。
  • 我也试过了,清除浏览器缓存和cookies,重新启动机器,django服务器但无济于事。我也重新创建了我的 virtualenv,尝试降级到 Django 1.9,但到目前为止没有任何效果

标签: javascript python django csrf httponly


【解决方案1】:

所以我找到了一个基于这里提到的 kambiz 的解决方案:Django CSRF check failing with an Ajax POST request

我将ajax参数部分修改为:

$.post('/api/jpush',
  $.param({'recipients': recipients, 'message': message, 'url': url,
           'url_title': url_title, 'priority': priority,
           'csrfmiddlewaretoken': $('input[name=csrfmiddlewaretoken]').val()}),
...

这仍然不能回答为什么 Django 将 csfr cookie 强制为 httponly 但至少我可以继续使用代码

【讨论】:

    猜你喜欢
    • 2012-06-07
    • 2011-09-28
    • 2017-12-04
    • 2019-10-28
    • 1970-01-01
    • 2010-09-06
    • 2019-11-15
    • 2011-04-01
    • 1970-01-01
    相关资源
    最近更新 更多