在通过API请求POST时,CSRF验证失败

时间:2014-03-07 13:07:49

标签: django rest backbone.js csrf django-csrf

我正在使用REST API编写网站。我在后端使用django和活塞(也使用corsheaders.middleware.CorsMiddleware和CORS_ORIGIN_ALLOW_ALL = True)。我使用backbone.js作为前端。我正在从客户端发送POST请求并收到错误:

CSRF verification failed. Request aborted.

我已经google了很多,并且所有解决方案都提供了类似“使用自动添加RequestContext的渲染快捷方式”之类的内容。但我没有看法,将从前端请求表格,不应该知道后端如何工作。这是我的scipt的代码

Question = Backbone.Model.extend({
    urlRoot: 'http://example.com/api/questions',

    defaults: {
        id: null,
        title: '',
        text: ''
    },

    initialize: function() {
        //alert(this.title);
    }
});

var question2 = new Question;
var questionDetails = {title: 'test title', text: 'test text'};
question2.save(questionDetails, {
    success: function(question) {
        alert(question.toJSON());
    }
});

2 个答案:

答案 0 :(得分:1)

django文档有关于如何设置jquery以通过ajax发送csrf令牌的说明。

https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax

您应该确保模板标记{% csrf_token %}在您的前端呈现内容。这样您就知道正在创建令牌并将其传递给前端。如果您按照上述文档中的说明进行操作,则应始终使用ajax请求发送csrf令牌。这就是我的一个网站的javascript(假设你使用的是jQuery)。

// Set up Django CSRF Token Protection
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');

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", csrftoken);
        }
    }
});

另外,请确保您的MIDDLEWARE_CLASSES设置中有'django.middleware.csrf.CsrfViewMiddleware'

答案 1 :(得分:0)

听起来你需要通过保存请求传递CSRF令牌。

一种解决方案是将CSRF令牌传递回请求它的模型,然后覆盖模型的保存方法,确保模型将CSRF令牌传回给它。

    Question = Backbone.Model.extend({
        urlRoot: 'http://example.com/api/questions',

        defaults: {
            csrf: null,
            id: null,
            title: '',
            text: ''
        },

        initialize: function() {
            //alert(this.title);
        }

        save: function( data, options ){

             data = $.extend( true, {
               csrf: this.get( 'csrf' )
             }, data );   

             options = _.extend( options, {
                 error: onError,
                 success: onSuccess
              } );

             // Call super method.
             Backbone.Model.prototype.save.apply( this, [ data, options ] );
        }

    });
相关问题