Джанго CSRF токен без форм - PullRequest
10 голосов
/ 19 октября 2011

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

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

... но получаю сообщение "Ошибка проверки CSRF. Запрос отменен".Ошибка 404.

Ответы [ 4 ]

13 голосов
/ 20 октября 2011

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

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

Также обратите внимание:

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

1 голос
/ 27 февраля 2016

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

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

см. Больше: https://stackoverflow.com/a/7715325/1743582

0 голосов
/ 07 марта 2018

Есть два шага в настройке токена 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');
        }
    });

}
0 голосов
/ 19 апреля 2016

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

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

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

...