2017-02-09 15 views
1

У меня странная проблема с CSRF в Django. Вот соответствующие части:Django ajax 403 из-за httponly cookie

В моем файла 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, а cookie csrftoken - http Только. Я установил CSRF_COOKIE_HTTPONLY в False в моем settings.py, поэтому я не понимаю, почему cookie принудительно выполняется как httpOnly. Я использую Django 1.10.

Благодаря

+0

У вас есть e только cookie только для http, прежде чем вы установите 'CSRF_COOKIE_HTTPONLY = False'. Попробуйте очистить свои файлы cookie и повторить попытку. – Alasdair

+0

Да, я установил его в файле 'settings.py', и я несколько раз удалял куки, но, согласно Firebug, он всегда возвращается как httponly. Я пробовал просматривать файлы cookie с помощью 'document.cookie', но он не показывает ни того, что подтверждает, что показывает firebug. – echodrome

+0

Убедитесь, что вы сбросили сервер, а затем очистили файлы cookie после изменения настроек. – Alasdair

ответ

0

Так что я нашел решение, основанное на том, что Камбиз упоминается здесь: Django CSRF check failing with an Ajax POST request

Я изменил АЯКС параметр часть к:

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

это еще не дает ответа, почему Джанго форсирует csfr cookie как httponly, но по крайней мере я могу продолжить работу с кодом