2015-09-26 3 views
1

прежде чем вы отметите это как дубликат, пожалуйста, прочитайте, поскольку я прошел через множество вопросов переполнения стека, но не нашел подходящего решения.Как сделать правильный вызов ajax в javascript для рамки django с защитой csrf?

Итак, проблема, с которой я столкнулся, я новичок в django и узнал о защите CSRF для запросов POST. Я успешно выполнил эти вызовы на странице, основанной не на ajax. Но текущий проект, над которым я работаю, - это одностраничное приложение. Таким образом, все вызовы проходят через ajax и в vanila JS не используют какую-либо библиотеку. Проблема, с которой я сталкиваюсь, заключается в том, что для первого запроса я получаю действительный токен CSRF, который я сгенерировал в шаблоне. Но после первого вызова ajax токен CSRF изменяется. Поэтому я хочу знать, какой правильный метод в django для такой ситуации. Должен ли я сделать все запросы с помощью токена CSRF как-то и сохранить их в переменной JS?

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

PS: Я предпочитаю коды в чистом JS не jquery или какой-либо другой структуре и не хотел бы отключать защиту csrf.

Я уже успел сохранить токен CSRF в cookie или переменной сеанса тем, что победил бы всю цель токена.

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

+1

Да, вы должны сохранить это в переменной JS и отправить его с помощью запроса ajax. Что именно вы пробовали, что не работает? –

+0

@ dan-klasson Я не пробовал это, но хотел знать правильный способ его обработки. Что относительно этого случая, если формы, основанные на ajax, смешиваются с нормальным. Каким будет решение в этом случае? – georoot

ответ

0

Проблема, с которой я столкнулся, заключается в том, что для первого запроса я получаю действительный токен CSRF, который я сгенерировал в шаблоне. Но после того, как сначала ajax вызовет изменения токена CSRF.

Я не верю, что это правда. В противном случае любое приложение django перестанет работать, если пользователь откроет более одной вкладки.

Вот решение, которое я использую на своих веб-серверах. Он работает так, как ожидалось, но я не следовал официальной рекомендации по получению маркерной ценности из файла cookie. Зачем? Меньше кода.

MyApp/templatetags/csrf_ajax.html

from django import template 

register = template.Library() 


@register.inclusion_tag('myapp/_csrf_ajax.html') 
def csrf_ajax(): 
    # https://docs.djangoproject.com/en/1.8/ref/csrf/#ajax 

    return {} 

_csrf_ajax.html

<script> 
(function() { 
    var csrf_token = "{{ csrf_token }}"; 
    function csrfSafeMethod(method) { 
     return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); 
    } 
    $.ajaxSetup({ 
     beforeSend: function(xhr, settings) { 
      if (!csrfSafeMethod(settings.type) && !this.crossDomain) { 
       xhr.setRequestHeader("X-CSRFToken", csrf_token); 
      } 
     } 
    }); 
})(); 
</script> 

Затем я использую этот templatetag на каждой странице, что я хочу установку CSRF АЯКС.

{% csrf_ajax %} 
0

csrttoken хранится в файлах cookie и не изменяется при каждом запросе ajax. У меня есть этот код в файле js и добавьте его на любую страницу, на которую нужно отправить сообщения ajax post (он использует jQuery и cookie, вам нужно перевести его на обычный JavaScript, если вы не хотите использовать внешние библиотеки):

var csrftoken = $.cookie('csrftoken'); 

function csrfSafeMethod(method) { 
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); 
} 

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