2015-08-13 1 views
2

Я разработал API загрузки файлов Django, которые получают опубликованные данные от клиента и сохраняют данные как файл.Django X-CSRFToken был установлен, но до сих пор запрещен 403

В соответствии с Django CSRF manual заголовок HTTP-запроса должен установить X-CSRFToken с использованием значения cookie csrftoken. Я установил X-CSRFToken по приведенному ниже коду, но запрос POST по-прежнему запрещен (403) сервером Django, как показано на рисунке ниже.

$(document).ready(function(){ 
    var authid 
    $.get("http://localhost:8000/v1/getAuthID?username=testuser1&password=123", function(data){ 
     authid = data["authid"]; 
     var csrftoken = $.cookie('csrftoken'); 
     console.log(csrftoken); 

     $.ajaxSetup({ 
      beforeSend: function(xhr, settings) { 
       xhr.setRequestHeader("X-CSRFToken", csrftoken); 
      } 
     }); 

     url = "http://localhost:8000/v1/file".replace("{authid}", authid).replace("{token}", csrftoken) 
     $.post(url, function(data){ 
     }) 
    }) 
}) 

enter image description here

Как вы преодолеваете Django CSRF по запросу POST отправки на сервер Django?

Спасибо!

+2

Почему вы так уверены, что это проблема CSRF? Я не вижу ничего плохого в обработке CSRF с первого взгляда. – knbk

+0

У меня получилось, что проверка CSRF не удалась. Запрос прерван. когда я проверил ответ 403. И я получаю тот же ответ, когда код добавления X-CSRFToken удаляется. – ybdesire

+2

Хорошо, вы можете проверить, соответствует ли файл cookie, отправленный в POST-запросе заголовком? – knbk

ответ

1

Переместить ajaxSetup за пределы функции успеха AJAX, как это требуется для запроса, а не после него.

$(document).ready(function(){ 
    var authid; 
    var csrftoken = $.cookie('csrftoken'); 
    console.log(csrftoken); 

    $.ajaxSetup({ 
     beforeSend: function(xhr, settings) { 
      xhr.setRequestHeader("X-CSRFToken", csrftoken); 
     } 
    }); 


    $.get("http://localhost:8000/v1/getAuthID?username=testuser1&password=123", function(data){ 
     authid = data["authid"]; 

     url = "http://localhost:8000/v1/file".replace("{authid}", authid).replace("{token}", csrftoken) 
     $.post(url, function(data){ 
     }) 
    }) 
}) 
+0

Спасибо за помощь :) Но у вас еще 403 ошибка с вашим кодом. – ybdesire

+1

Является ли это опечаткой, что ваш экран на экране консоли запрашивает localhost: 8003, но ваш фрагмент кода - localhost: 8000 или это интенция? – justcompile

+0

JS запускается на локальном сайте localhost: 8003. И сервер Django работает на localhost: 8000. – ybdesire

1

Я использую Javascript ниже код, который берет на себя всю CSRF тему для Ajax вызовов:

// This function gets cookie with a given name 
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'); 

/* 
The functions below will create a header with csrftoken 
*/ 

function csrfSafeMethod(method) { 
    // these HTTP methods do not require CSRF protection 
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); 
} 
function sameOrigin(url) { 
    // test that a given url is a same-origin 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)); 
} 

$.ajaxSetup({ 
    beforeSend: function(xhr, settings) { 
     if (!csrfSafeMethod(settings.type) && sameOrigin(settings.url)) { 
      // Send the token to same-origin, relative URLs only. 
      // Send the token only if the method warrants CSRF protection 
      // Using the CSRFToken value acquired earlier 
      xhr.setRequestHeader("X-CSRFToken", csrftoken); 
     } 
    } 
}); 

Просто включите его после того, как JQuery.

+0

Спасибо @Danial за код:). getCookie ('csrftoken') не работает для моей ситуации. Я не использовал шаблон Django, и я общаюсь с API, разработанным Django только JS. Поэтому я не могу получить cookie 'csrftoken'.Похоже, это потому, что cookie-ответ от Ajax не может установить cookie-файл браузера. Я все еще исследую это ... ... – ybdesire

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