Джанго CSRF терпит неудачу с ajax - PullRequest
1 голос
/ 30 ноября 2011

У меня проблема с использованием Django CSRF с Ajax.Я получаю 403 Запрещено.Я сделал все то, что я обычно делаю с CSRF с не-ajax-запросом, но у меня все еще есть эта проблема.Я думаю, что это как-то связано с фрагментом javascript на https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax.

$(document).ajaxSend(function(event, xhr, settings) {
   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;
   }
   function sameOrigin(url)
   {
      // url could be relative or scheme relative or absolute
      var host = document.location.host; // host + port
      var protocol = document.location.protocol;
      var sr_origin = '//' + host;
      var origin = protocol + sr_origin;
      // Allow absolute or scheme relative URLs to same origin
      return (url == origin || url.slice(0, origin.length + 1) == origin + '/') ||
             (url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') ||
             // or any other URL that isn't scheme relative or absolute i.e relative.
             !(/^(\/\/|http:|https:).*/.test(url));
   }
   function safeMethod(method)
   {
      return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
   }
   if (!safeMethod(settings.type) && sameOrigin(settings.url))
   {
      xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
   }
});

В настоящее время я не использую этот фрагмент, главным образом потому, что не понимаю ни слова об этом и не знаюНе знаю, как включить его в мой jjery ajax-вызов:

function submit_search()
{
   $.ajax({
             data:     {query: document.search_form.query.value},
             datatype: 'json',
             success:  function(data, textStatus, XMLHttpRequest)
                       {
                          if (data)
                          {
                             if (check_authentication(data))
                             {
                                $("#results").html("");
                                var results = data[0];
                                var length = data[1];
                                for (var index = 0; index < results.length; ++index)
                                {
                                   var result = results[index];
                                   $("#results").append("<p><a href='/entities/" + result["id"] + "'>" + result["name"] +
                                                        "</a><br />" + result["description"] + "</p>");
                                }
                             }
                             else
                             {
                                offer_login();
                             }
                          }
                       },
             type:     'POST',
             url:      '/ajax/search',
          });
}

Кто-нибудь знает, как мне добавить этот фрагмент в мой код?

Также пробовал:

$.ajaxSetup({
    beforeSend: function(xhr, settings) {
        if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
            // Only send the token to relative URLs i.e. locally.
            xhr.setRequestHeader("X-CSRFToken",
                                 $("#csrfmiddlewaretoken").val());
        }
    }
});

но, похоже, это тоже не работает, хотя я не уверен, стоит ли мне что-то делать с битом о #csrfmiddlewaretoken в моей форме

Спасибо

Ответы [ 2 ]

3 голосов
/ 01 декабря 2011

Все, что вам нужно сделать, это вставить блок кода таким образом, чтобы код в нем выполнялся. Если у вас есть глобальный файл JS, вы можете просто добавить этот JavaScript в конец указанного файла, и это решит проблему.

1 голос
/ 28 января 2013

хорошо, требуется пара шагов, как указано в https://docs.djangoproject.com/en/dev/ref/contrib/csrf/

Чтобы подвести итог утомительного документа django, вам необходимо: 1. установить плагины jquery.cookie 2. убедитесь, что crsf_token обходит

например, в вашем шаблоне форма должна содержать следующее скрытое поле

<input type="hidden" name="csrfmiddlewaretoken" value="{{csrf_token}}"/>

В вашем ajax-запросе вы должны использовать такие вещи, как

csrf_token = $.cookie('csrftoken');
$.ajax({
   url: '/url/',
           type: 'POST',
           beforeSend: function(xhr, settings) {
               xhr.setRequestHeader("X-CSRFToken", csrf_token);
            },
           data: $('.form').serialize(), //assume you are submit a form
 }).done(function(response){
         console.log(response)
 });

Один маленький трюк, который вы можете пропустить: ваша целевая страница (не-ajax) будет нуждаться в декораторе @csrf_protect для настройки cookie, если вы этого не сделаете, cookie не будет существовать, а метод потерпит неудачу , Если вы не хотите создавать декоратор @csrf_protect, вы всегда можете обратиться к документу и настроить файл cookie. В любом случае будет работать.

Надеюсь, это поможет.

...