Ajax CSRF проблема в Джанго 1.3 - PullRequest
6 голосов
/ 31 марта 2011

Согласно документации django, для запроса поста ajax в 1.3 (по крайней мере, с Jquery) нам просто нужно добавить этот фрагмент в основной файл js. Этот фрагмент получает csrftoken из файлов cookie, а затем настраивает его для всех запросов ajax. Это работает, но что если csrftoken не существует в файлах cookie? Я подумал, что render_to_response и render одновременно автоматически проверяют наличие csrftoken в сеансах и устанавливают его для нас, если токена нет. Но это не так. Итак, мне нужно реализовать это самостоятельно? Или, может быть, есть другой способ защиты ajax csrf?

Ответы [ 5 ]

11 голосов
/ 21 сентября 2011

Если на странице, которая уже использует {% csrf_token%}, нет формы, файл cookie не будет отправлен.Поэтому, как вы заметили, вы получите ошибку при попытке использовать Ajax на такой странице.Это приведет к нестабильному поведению, если у вас есть сайт со смесью страниц с различными комбинациями форм и сообщений AJAX.

Это уже было сообщено и исправлено: https://code.djangoproject.com/ticket/15354

Решение в патче, которое должно появиться с 1.3.1, это декоратор sure_cookie_csrf.Этот декоратор не существует в 1.3 или 1.2.5

Однако ждать не нужно.Просто добавьте эту строку в любое представление, в котором AJAX публикует форму CSRF:

request.META["CSRF_COOKIE_USED"] = True

Пример:

def calculator(request):
    request.META["CSRF_COOKIE_USED"] = True
    return render_to_response('calc.html', {'form': CalcForm()})

FYI - это именно то, что делает этот декоратор.

3 голосов
/ 09 сентября 2011

Что касается Ajax, вы должны передавать токен csrf при каждом запросе.Для jQuery я использую следующий код:

$.ajaxPrefilter(function(options, originalOptions, jqXHR) {
    if(!options.crossDomain) {
        if(options.data) {
            options.data += "&";
        } else {
            options.data = "";
        }
        options.data += "csrfmiddlewaretoken={{csrf_token}}";
    }
});
3 голосов
/ 31 марта 2011

Ваш файл cookie будет содержать только токен CSRF, если в шаблоне использовался тег {% csrf_token %} для генерации запроса или если вы вызываете get_token (с объектом request в качестве аргумента) из django.middleware.csrf. * * 1005

Функция get_token устанавливает метаинформацию для объекта request, которая, в свою очередь, указывает промежуточному программному обеспечению django.middleware.csrf.CsrfViewMiddleware установить cookie.

1 голос
/ 29 августа 2012

Если вы используете декоратор @csrf_protect, убедитесь, что и представление с формой, и представление о том, что данные публикуются, используют декоратор.

У меня была похожая проблема.У меня был только @csrf_protect в представлении постов, которое хорошо работало при локальном тестировании, но когда я начал работу, у меня возникла проблема с проверкой 403, добавление декоратора для просмотра страницы исправило это

1 голос
/ 21 сентября 2011

Один из способов обойти это - использовать ранее существующую форму в качестве отправной точки для ваших данных AJAX.

<form id="ajax_form" stye="display: none;">{% csrf_token %}</form>

Затем вы можете использовать это в своем JavaScript с помощью функции Serialize JQuery.:

var data = $('#ajax_form').serialize();
data += "&mydata=69";

Вы даже можете использовать скрытые поля в этой скрытой форме, чтобы вам не приходилось использовать конкатенацию строк для построения данных POST.

...