2015-09-15 9 views
0

Привет, вот в чем проблема: Я делаю логин через ajax без перезагрузки страницы - просто нажмите кнопку «Войти», указав свое имя пользователя и пароль, а также запрос с двумя файлами cookie, sessionid и csrftoken, идет. Обратите внимание, что страница НЕ была перезагружена. Сразу после я запуск другого запроса Ajax (POST), который требует авторизованы пользователя:Django Ajax login then ajax call - csrf 403 error

@login_required                        
@ajax                          
def member_index(request): 
    .... 

я получаю 403 Forbidden ошибки, которая исходит от CsrfMiddleware (потому что если я отключить его в настройках, все работает). Вопрос в том, что я делаю неправильно? Если я перезагрузите страницу, будет выполнен запрос ajax. Я понюхал файлы cookie в браузере (sessionid и csrftoken), и все выглядит хорошо. ]

+0

Вам нужно указать значение csrftoken в POST. – Joseph

+0

Я проверил этот запрос почты от браузера Chrome: установлен csrftoken. И я написал, что после обновления страницы запрос работает правильно, поэтому я устанавливаю в javaScript csrfToken. Я думаю, что проблема в другом месте. Но спасибо за быстрый ответ. – friko

ответ

0

Вам нужно добавить csrftoken к вашему AJAX вызова, вы можете сделать это с помощью этого кода, приведенные в данном ответе (Django CSRF check failing with an Ajax POST request)

$.ajaxSetup({ 
    beforeSend: function(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; 
     } 
     if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) { 
      // Only send the token to relative URLs i.e. locally. 
      xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')); 
     } 
    } 
}); 
+0

Я уже это делаю. Если бы я этого не сделал, тогда моя вторая просьба не сработала. Я проверил вкладку сети в Google Chrome, где я могу заметить ответ и запрос. CsrfToken устанавливается вызовом ajax. – friko

0

решенный. Спасибо всем за помощь. я должен был добавить этот обработчик:

$(document).ajaxSend(function(event, xhr, settings) { 
    if (settings.type == 'POST' || settings.type == 'PUT' || settings.type == 'DELETE') { 
     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; 
     } 
     if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) { 
      // Only send the token to relative URLs i.e. locally. 
      xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')); 
     } 
    } 
}); 

Он обновляет поле «X-CSRFToken» каждый раз, когда Ajax должен быть отправить. AjaxSetup устанавливается только в первый раз во время перезагрузки страницы. Тогда любой входящий запрос ajax с новым csrftoken должен обновить поле «X-CSRFToken».