2015-07-14 4 views
0

Я разработал свое приложение для Linux, и запросы AJAX работают нормально. Я вытащил приложение на компьютер с Windows, но запросы AJAX терпят неудачу, я просто получил 403 Forbidden ошибку. От поиска в Интернете я думаю, что это проблема с токеном csrf. В Linux я вижу csrftoken:"AjQzJy3tRZ2awslgdibkDTvQgANFQKmP" в разделе «Cookies» запросов AJAX. Я не вижу cookies в Windows.Django - AJAX не работает из-за того, что токен csrf не работает на окнах

Это код Javascript, который я использую для получения файла cookie csrf. Именно из https://docs.djangoproject.com/en/1.8/ref/csrf/

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

Это где я подать запрос AJAX:

function refreshInformation(){ 
$.ajax({ 
    type: "POST", 
    url: "get_flows_info", 
    data: { 
      csrfmiddlewaretoken: getCookie('csrftoken') 
    } 
    dataType : "json", 
    async : true, 
    error : function(data){ 
     alert('AJAX error:' + data); 
    }, 
    success : function(json_data){ 
      // do stuff... 
    }, 
}); 
} 

Это мнение испрашивается:

def get_flows_info(request): 
    if request.is_ajax(): 

      # do stuff... 

     return HttpResponse(json.dumps(ret), content_type='application/json') 

Я нашел это: Django CSRF check failing with an Ajax POST request но JQuery не имеет никакого значения.

Любая помощь?

Спасибо.

+0

Вы пытались отправить заголовок 'X-CSRFToken'? –

+0

Кроме того, что возвращает 'getCookie ('csrftoken') вызов? Я предполагаю, что ['CSRF_COOKIE_NAME'] (https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-CSRF_COOKIE_NAME) имеет значение по умолчанию. –

+0

В Linux он возвращает 'AjQzJy3tRZ2awslgdibkDTvQgANFQKmP', в Windows он возвращает null ... – BelegNeurion

ответ

3

Вот что можно сделать:

  1. Проверить CSRF токен имя куки.

    Для получения дополнительной информации см. CSRF_COOKIE_NAME.

  2. Добавить ensure_csrf_cookie декоратор на ваш взгляд (тот, который отображает страницу).

    По the docs:

    Предупреждение

    Если ваше мнение не делает шаблон, содержащий csrf_token тег шаблона, Django не может установить маркер куки CSRF. Это часто встречается в тех случаях, когда формы динамически добавляются на страницу. Чтобы устранить этот случай, Django предоставляет декодер вида, который заставляет настройку файла cookie: ensure_csrf_cookie().

  3. Если предположить, что CSRF токен имя куки csrftoken, попробуйте отправить X-CSRFToken заголовок.

    $.ajax({ 
        // Your options here. 
        headers: {'X-CSRFToken': getCookie('csrftoken')} 
    }); 
    

Read Cross Site Request Forgery protection для получения дополнительной информации.

+0

Спасибо за ответ, но getCookie возвращает null, так что это не сработало. – BelegNeurion

+0

@BelegNeurion Проверьте имя файла cookie-файла CSRF, напечатав ['CSRF_COOKIE_NAME'] (https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-CSRF_COOKIE_NAME) из настроек. –

+0

Где его напечатать? Я попробовал 'print (CSRF_COOKIE_NAME)', где я вызываю свой индексный указатель, но он говорит, что он не определен. – BelegNeurion

0

То, что я сделал, это просто what the Doc suggests: добавьте заголовок ко всем запросам Ajax, а не POSTing csrftoken в каждом запросе ajax. Он работает для меня (только для тестирования в Linux)

Первая часть - получить файл cookie, как вы это делали.

<script type="text/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)); 
    } 

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

наконец, сделать свой вызов Ajax, как обычно, без добавления csrftoken в качестве дополнительных параметров.

Полезно, если вы хотите выполнить несколько вызовов ajax на одной странице. Также рекомендуется. И если раньше у вас нет защиты CSRF, и теперь вы должны добавить ее, это не связано с изменением существующего кода.

Повторите эти строки на каждой странице, где используется ajax, вместо повторения токена в каждом вызове ajax.

Смежные вопросы