Jquery 和 Django CSRF 令牌

Posted

技术标签:

【中文标题】Jquery 和 Django CSRF 令牌【英文标题】:Jquery and Django CSRF Token 【发布时间】:2012-01-26 17:57:18 【问题描述】:

我有 2 个 html 页面。

一个父页面和一个子页面。子页面包含一个提交按钮,该按钮在父页面上运行代码以提交 Ajax 消息。

我使用 $.load() 方法加载子页面,然后在单击按钮时运行 $.ajax .POST 方法。此 post 方法仅将 JSON 字符串传递给 Python 代码。

当我在除 IE 之外的任何浏览器上执行此操作时,它都可以正常工作。但是,当我在 IE 中运行此代码时。我收到有关 CSRF 令牌的 Python / Django 错误。

认为原因是因为子页面只是当前页面本身的刷新,服务器端代码正在运行。

有谁知道我应该如何让它发挥作用。

干杯,

【问题讨论】:

【参考方案1】:

您没有通过 POST 传递 csrf 令牌。尝试做我在 data 中所做的事情。即获取 csrf 令牌(或您自己的方法)并将其传递到您的参数中。

$.ajax(
    url : url,
    type: "POST",
    data : csrfmiddlewaretoken: document.getElementsByName('csrfmiddlewaretoken')[0].value,
    dataType : "json",
    success: function( data )
        // do something
    
);

【讨论】:

这种方法很好,但是如果您发出许多 ajax 请求,您可能会发现将 CSRF 令牌作为标头传递会更方便。如需更多信息,请参阅django docs。 我觉得data: ..., 'csrfmiddlewaretoken': ' csrf_token ', ... 更直接。 或在.html 模板中:<script> var django_csrf_token = ' csrf_token '; </script> 可从静态.js 使用。【参考方案2】:

如果您要发送 POST 请求正文,则可能更容易将 csrf 令牌添加为请求标头。我发现这种方法更容易阅读,因为它不会用令牌混淆请求正文。大多数 AJAX 请求将按照 Django 文档的建议将 csrf 令牌作为标头发送。

function startTest(testId) 
  var payload = JSON.stringify(
    test_id : testId
  );
  $.ajax(
    url: "/test-service/",
    method: "POST",
    headers: 'X-CSRFToken': ' csrf_token ',
    data: payload,
    dataType: "json"
  ).done(function(response) 
    console.log(response.id + " " + response.name);
  ).fail(function (error) 
      console.log(error);
  );

【讨论】:

【参考方案3】:

来自 CSRF 和 AJAX 上的 docs:

CSRF 令牌也存在于 DOM 中,但只有在模板中使用 csrf_token 明确包含。 cookie 包含规范令牌; CsrfViewMiddleware 将更喜欢 cookie 而不是 DOM 中的令牌。无论如何,如果令牌存在于 DOM 中,则保证您拥有 cookie,因此您应该使用 cookie!

示例 (也来自文档)

// using jQuery
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');

或者可以使用任何其他与 cookie 交互的方式。

【讨论】:

以上是关于Jquery 和 Django CSRF 令牌的主要内容,如果未能解决你的问题,请参考以下文章

如何在 AJAX 中传递 Django csrf 令牌(没有 jQuery)

JQuery:一起发布 FormData 和 csrf 令牌

如何将 Django 的 CSRF 令牌添加到 jQuery POST 请求的标头?

django的csrf

django 1.3 中带有 jquery 和 $.post 的 CSRF

在 django 中使用 ajax 表单发布 csrf 令牌的这种方法有啥问题?