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

Posted

技术标签:

【中文标题】django 1.3 中带有 jquery 和 $.post 的 CSRF【英文标题】:CSRF with jquery and $.post in django 1.3 【发布时间】:2011-09-05 21:03:33 【问题描述】:

在 django 1.3 中,您现在必须使用 csrf,即使使用 ajax。 我使用 jquery,现在我想将 csrf 令牌添加到 $.post。我怎样才能做到这一点?我对 jquery 不是很熟练,所以最好有一个好的描述。

这是一个评分应用程序,点击星号时会发送帖子。 我看过django docs,但不明白在我的情况下该怎么做。我的代码如下:

$(function()   
            $("#avg").children().not(":input").hide();
            $("#rating-widget").children().not("select").hide();    

            $caption = $("<span/>");

            $("#avg").stars(captionEl: $caption);
            $("#rating-widget").stars(
                inputType: "select",
                cancelShow: false,
                captionEl: $caption,
                callback: function(ui, type, value)
-------------->     $.post($("#rating-widget").attr("action"), score: value, function(data)

                    );
                
            );
               $caption.appendTo("#rating-widget");

);

应该说javascript不在模板中,而是在静态文件中。 最好把它放在模板中,这样我就可以使用 csrf_token

提前致谢!

【问题讨论】:

【参考方案1】:

将此代码放在您的函数之前。它将处理 CSRF。

$('html').ajaxSend(function(event, xhr, settings) 
    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;
    
    if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) 
        // Only send the token to relative URLs i.e. locally.
        xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
    
);

【讨论】:

我刚刚找到了一个edited version,他们使用的是 ajaxSetup。它对我有用:) 不知道这么容易!谢谢!【参考方案2】:

在django documentation 中,您可以找到关于如何在每个 ajax 请求中自动包含 csrf 令牌的简单说明!

【讨论】:

正如问题中所说:我已经检查了那个地方,但无法理解并将其放入我的代码中。但无论如何感谢您的帮助:) 直到我删除了 ajaxSetup 中的 if 语句,才对我有用,只有 xhr.setRequestHeader("X-CSRFToken", csrftoken);【参考方案3】:

您不必使用表单!只需创建一个绑定到“星标”帖子的函数的新 url。例如

(r'^myapp/star-post/(?P<post_id>.*)/$','myapp.views.myview')

因此,如果您向该 url 发送请求,它将在您的数据库中找到该帖子,将字段更改为“已加星标”并返回对 ajax 的响应。

然后你可以有一个成功的回调函数,它会相应地改变 CSS(填充星号等)。这样,您就不必担心 CSRF。

但是您可能会问,那么跨站点脚本攻击呢!好吧,如果您将用户身份验证与 cookie 验证一起使用,则不必担心!啊,你很高兴。

【讨论】:

这正是我所做的。问题是我必须将它存储在数据库中,它提示我输入 csrf 令牌。问题是在我将 fra 1.2 更新到 1.3 后出现的,你使用了 csrf 令牌 - 即使使用 ajax。我想知道如何在使用 ajax 发送的请求中包含 csrf 令牌 @tmpethick 即使使用 csrf_exempt 装饰器?从 django.views.decorators.csrf 导入 csrf_exempt

以上是关于django 1.3 中带有 jquery 和 $.post 的 CSRF的主要内容,如果未能解决你的问题,请参考以下文章

django2中带有router.urls的命名空间

django中带有额外条件的左外连接

jinja2中带有html标签的Django模板

标题和行中带有复选框的Jquery数据表:选择所有复选框不起作用

MVC4 中带有 jquery.validate.unobtrusive 的文件

html模板django python中带有拆分的子字符串