如何在 javascript 中使用 % csrf_token %

Posted

技术标签:

【中文标题】如何在 javascript 中使用 % csrf_token %【英文标题】:How to use % csrf_token % in javascript如何在 javascript 中使用 % csrf_token % 【发布时间】:2013-07-19 22:26:53 【问题描述】:

在我的用户页面中,我使用 ajax 进行了适当的编辑。当我单击编辑时,它工作正常。但是当我提交表单时,它什么也没做。当我检查时,这是错误:

CSRF verification failed. Request aborted.

那么,如何在我的 javascript 中放置 % csrf_token %?请指教。 谢谢。

edit.js:

function bookmark_edit() 
    var item = $(this).parent();
    var url = item.find(".title").attr("href");
    item.load("/save/?ajax&url=" + escape(url), null, function () 
        $("#save-form").submit(bookmark_save);
        );
    return false;
    

$(document).ready(function () 
    $("ul.bookmarks .edit").click(bookmark_edit);
    );

function bookmark_save() 
    var item = $(this).parent();
    var data = 
        url: item.find("#id_url").val(),
        title: item.find("#id_title").val(),
        tags: item.find("#id_tags").val()
        ;
    $.post("/save/?ajax", data, function (result) 
        if (result != "failure") 
        item.before($("li", result).get(0));
        item.remove();
        $("ul.bookmarks .edit").click(bookmark_edit);
        
        else 
            alert("Failed to validate bookmark before saving.");
        
        )
        return false;
    

save_form.html

<form id = "save-form" method="post" action="/save/">
% csrf_token %
    form.as_p
    <input type="submit" value="Save" />
</form>

user_page.html:

% extends "base.html" %
% block external %
    <script type = "text/javascript" src="% static "assets/js/bookmark_edit.js" %"></script>
% endblock %
% block title % username % endblock %
% block head % Bookmarks for username % endblock %
% block content %
    % include "bookmark_list.html" %
% endblock %

view.py:

@login_required(login_url='/login/')
def bookmark_save_page(request):
    ajax = request.GET.has_key('ajax')
    if request.method == 'POST':
        form = BookmarkSaveForm(request.POST)
        if form.is_valid():
            bookmark = _bookmark_save(request, form)
            if ajax:
                variables = RequestContext(request, 
                    'bookmarks':[bookmark],
                    'show_edit':True,
                    'show_tags':True
                    )
                return render_to_response('bookmark_list.html', variables)
            else:
                return HttpResponseRedirect('/user/%s/' % request.user.username
                    )
        else:
            if ajax:
                return HttpResponseRedirect('failure')
    elif request.GET.has_key('url'):
        url = request.GET['url']
        title = ''
        tags = ''

        try:
            link = Link.objects.get(url=url)
            bookmark = Bookmark.objects.get(
                link=link,
                user = request.user
                )
            title = bookmark.title
            tags = ' '.join(
                tag.name for tag in bookmark.tag_set.all()
                )
        except ObjectDoesNotExist:
            pass
        form = BookmarkSaveForm(
            'url':url,
            'title':title,
            'tags':tags
            )
    else:
        form = BookmarkSaveForm()

    variables = RequestContext(request, 
        'form': form
        )
    if ajax:
        return render_to_response(
            'bookmark_save_form.html',
            variables
            )
    else:
        return render_to_response('bookmark_save.html',variables)

【问题讨论】:

【参考方案1】:

您没有发送服务器生成的 csrf_token 用于 POST 以验证数据的有效性。因此出现错误。

作为请求的data部分的一部分,您需要发送令牌

csrfmiddlewaretoken: ' csrf_token ' 

类似的东西

var data = 
    url: item.find("#id_url").val(),
    title: item.find("#id_title").val(),
    tags: item.find("#id_tags").val(),
    csrfmiddlewaretoken: ' csrf_token ' 
;

或者你可以简单地这样做:

var data = $('form').serialize()

如果您想将整个表单作为字典发送

【讨论】:

我试过csrfmiddlewaretoken: ' csrf_token' 但它并没有太大帮助。你能解释一下如何将整个作为字典发送吗? var data = $('form').serialize() 会将整个表单作为字典发送。 谢谢!这个有效! bdw 你能给我推荐一些关于最新 django 版本和 javascript 的好书吗? 我分别深入学习了 jQuery 和 Django,这帮助我根据自己的需要将两者结合在一起。我建议您在线阅读大量可用的博客,这些博客可以帮助您将各个部分拼凑起来。如果您遇到困难,*** 随时为您提供帮助。 书里有没有,csrf相关的问题?【参考方案2】:

这是我使用的。不过不确定它是否适用于您的情况。

// sending a csrftoken with every ajax request
function csrfSafeMethod(method) 
    // these HTTP methods do not require CSRF protection
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));

$.ajaxSetup(
    crossDomain: false, // obviates need for sameOrigin test
    beforeSend: function(xhr, settings) 
        if (!csrfSafeMethod(settings.type)) 
            xhr.setRequestHeader("X-CSRFToken", $.cookie('csrftoken'));
        
    
);

【讨论】:

【参考方案3】:

var csrftoken = Cookies.get('csrftoken');

xhr.setRequestHeader("X-CSRFToken", csrftoken);

enter link description here

【讨论】:

以上是关于如何在 javascript 中使用 % csrf_token %的主要内容,如果未能解决你的问题,请参考以下文章

Rails - 如何向用 javascript 创建的表单添加 CSRF 保护?

如何绕过csrf保护,并在burp suite中使用intruder?

如何在 django 中应用 csrf_token

如何在表单的 AJAX 发布请求中传递 CSRF 令牌?

如何在 Javascript 生成的 HTML 表单中包含 Django 1.2 的 CSRF 令牌?

保护 oauth 不记名令牌免受 javascript 应用程序中的 XSS、CSRF 等攻击