Токен Django CSRF без форм

звучит странно, но как насчет сценария публикации содержимого с помощью Javascript (например, AJAX) без использования формы (можно было бы прочитать несколько содержимого с поверхности).

где я должен разместить тег шаблона csrf_token? Я уже добавил исправление AJAX: https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax

...но я получаю " проверка CSRF не удалась. Запрос прерван."Ошибка 404.

4 ответов


вы должны установить пользовательский заголовок HTTP,X-CSRFToken, в вашем запросе AJAX. Смотри:https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax

Если вы уже следовали этому совету, он должен работать. Используйте что-то вроде Firebug для мониторинга отправляемого запроса и проверки заголовков, чтобы убедиться, что пользовательский заголовок действительно передается. Если это не так, проверьте свою реализацию еще раз, чтобы убедиться, что вы сделали это так же, как документы описывать.

обратите внимание:

из-за ошибки, введенной в jQuery 1.5, приведенный выше пример будет работать неправильно в этой версии. Убедитесь, что вы используете хотя бы jQuery 1.5.1.


это просто с этот код:

$.ajaxSetup({ data: {csrfmiddlewaretoken: '{{ csrf_token }}' },});

подробнее:https://stackoverflow.com/a/7715325/1743582


один токен CSRF присваивается каждому сеансу (т. е. каждый раз, когда вы входите в систему). Поэтому, прежде чем вы захотите получить некоторые данные, введенные пользователем, и отправить этот вызов ajax какой-либо функции, защищенной csrf_protect decorator, попробуйте найти функции, которые вызываются, прежде чем вы получаете эти данные от пользователя. Е. Г. некоторые шаблоны должны быть оказаны на котором пользователь вводит данные. Этот шаблон отображается какой-то функцией. В этой функции вы можете получить токен csrf как следует: csrf = запрос.COOKIES ['csrftoken'] теперь передают это значение csrf в контекстном словаре, против которого отображается соответствующий шаблон. Теперь в этом шаблоне напишите эту строку: теперь в вашей функции javascript, прежде чем сделать запрос ajax, напишите следующее: var csrf = $('#csrf').val () это выберет значение токена, переданного шаблону, и сохранит его в переменной csrf. Теперь при вызове ajax в ваших данных post передайте это значение: "csrfmiddlewaretoken": csrf

Это будет работать даже если вы не реализуете формы django.

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


есть два шага в настройке токена CSRF, если вы хотите опубликовать без формы. В основном получить csrftoken из Cookie и установите заголовок с csrftoken (перед публикацией данных).


1) получаем csrftoken из Cookie.

// Function to GET csrftoken from Cookie
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');

2) Как только у вас есть csrftoken, вы должны установить заголовок с csrftoken (перед публикацией данных).

function csrfSafeMethod(method) {
    // these HTTP methods do not require CSRF protection
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}

// Function to set Request Header with `CSRFTOKEN`
function setRequestHeader(){
    $.ajaxSetup({
        beforeSend: function(xhr, settings) {
            if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                xhr.setRequestHeader("X-CSRFToken", csrftoken);
            }
        }
    });
}

function postSomeData() {
    .....
    setRequestHeader();

    $.ajax({
        dataType: 'json',
        type: 'POST',
        url: "/url-of-some-api/",
        data: data,
        success: function () {
            alert('success');
        },
        error: function () {
            alert('error');
        }
    });

}