没有表格的Django CSRF令牌

听起来很奇怪但是使用Javascript(例如AJAX)发布内容而不使用表单的情况如何(可以从表面读取多个内容) .

我应该在哪里放置csrf_token模板标签?我已经添加了AJAX修复:https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax

...但我得到“CSRF验证失败 . 请求中止 . ” 404错误 .

回答(4)

2 years ago

您必须在AJAX请求中设置自定义HTTP标头 X-CSRFToken . 见:https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax

如果你已经遵循了这个建议,那应该是有效的 . 使用像Firebug这样的东西来监视正在发送的请求并检查标头以确保真正传递自定义标头 . 如果不是,那么请再次检查您的实施,以确保您按照文档描述的那样执行 .

另请注意:

由于jQuery 1.5中引入了一个错误,上面的示例将无法在该版本上正常运行 . 确保你至少运行jQuery 1.5.1 .

2 years ago

使用此代码很简单:

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

看到更多:https://stackoverflow.com/a/7715325/1743582

2 years ago

每个会话分配一个CSRF令牌(即每次登录时) . 因此,在您希望获取用户输入的某些数据并将其作为ajax调用发送到受csrf_protect装饰器保护的某个函数之前,请尝试在从用户获取此数据之前查找正在调用的函数 . 例如 . 必须呈现某些模板,用户在该模板上输入数据 . 该模板由某些函数呈现 . 在此函数中,您可以按如下方式获取csrf标记:csrf = request.COOKIES ['csrftoken']现在在上下文字典中传递此csrf值,以对照哪个模板进行渲染 . 现在在该模板中写下这一行:现在在你的javascript函数中,在发出ajax请求之前,写下这个:var csrf = $('#csrf') . val()这将选择传递给模板的token的值并将其存储在变量中CSRF . 现在在进行ajax调用时,在你的帖子数据中,也传递这个值:“csrfmiddlewaretoken”:csrf

即使您没有实现django表单,这也会有效 .

事实上,这里的逻辑是:你需要你可以从请求获得的令牌 . 所以你只需要确定登录后立即调用的函数 . 一旦你有了这个令牌,要么再做一个ajax调用来获取它,或者把它传递给你的ajax可以访问的模板 .

2 years ago

如果您希望在没有表单的情况下发布,则配置CSRF令牌有两个步骤 . 基本上从Cookie中获取 csrftoken ,并使用csrftoken设置Header(在POST数据之前) .


1)从Cookie中获取 csrftoken .

// 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设置Header(在POST数据之前) .

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');
        }
    });

}