如何使用Django和AngularJS创建POST请求(包括CSRF令牌)

Tho*_*mel 23 django post angularjs

我正在尝试使用angular.js创建一个POST请求到这个Django视图.

class PostJSON4SlickGrid(View):
    """
    REST POST Interface for SlickGrid to update workpackages
    """

    def post(self, request, root_id, wp_id, **kwargs):
        print "in PostJSON4SlickGrid"
        print request.POST
        return HttpResponse(status=200)
Run Code Online (Sandbox Code Playgroud)

因此我创建了这个资源.

myModule.factory('gridData', function($resource) {
    //define resource class
    var root = {{ root.pk }};
    return $resource('{% url getJSON4SlickGrid root.pk %}:wpID/', {wpID:'@id'},{
            get: {method:'GET', params:{}, isArray:true},
            update:{method:'POST'}
    });
});
Run Code Online (Sandbox Code Playgroud)

在控制器中调用get方法可以正常工作.该网址被翻译为http://127.0.0.1:8000/pm/rest/tree/1/.

function gridController($scope, gridData){
    gridData.get(function(result) {
        console.log(result);
        $scope.treeData = result;
        //broadcast that asynchronous xhr call finished
        $scope.$broadcast('mySignal', {fake: 'Hello!'});  
    });
}
Run Code Online (Sandbox Code Playgroud)

我正面临执行更新/ POST方法的问题.

item.$update();
Run Code Online (Sandbox Code Playgroud)

URL被转换为http://127.0.0.1:8000/pm/rest/tree/1/345,缺少尾部斜杠.在URL定义中不使用尾部斜杠时,可以轻松避免这种情况.

url(r'^rest/tree/(?P<root_id>\d+)/(?P<wp_id>\d+)$', PostJSON4SlickGrid.as_view(), name='postJSON4SlickGrid'),
Run Code Online (Sandbox Code Playgroud)

代替

url(r'^rest/tree/(?P<root_id>\d+)/(?P<wp_id>\d+)/$', PostJSON4SlickGrid.as_view(), name='postJSON4SlickGrid'),
Run Code Online (Sandbox Code Playgroud)

使用没有尾部斜杠的变通方法,我现在得到403(禁止)状态代码,这可能是因为我没有在POST请求中传递CSRF令牌.因此,我的问题归结为我如何将CSRF令牌传递给由angular创建的POST请求?

我知道这种通过标头传递csrf令牌的方法,但我正在寻找将令牌添加到post请求主体的可能性,如此处所示.在角度中是否可以将数据添加到帖子请求主体?

作为附加读物,可以查看有关资源,删除的尾部斜杠以及当前具有的限制资源的讨论:disc1disc2.在其中一个讨论中,作者之一建议目前不使用资源,而是使用这种方法.

Ano*_*oyz 39

我知道这是超过10岁,但如果有人绊倒在同一问题上,角JS已经有一个CSRF饼干取机制(开始于1.1.5 AngularJS的版本),你只需要告诉角度名称是什么django使用的cookie,以及它应该用来与服务器通信的HTTP头.

使用模块配置:

var app = angular.module('yourApp');
app.config(['$httpProvider', function($httpProvider) {
    $httpProvider.defaults.xsrfCookieName = 'csrftoken';
    $httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
}]);
Run Code Online (Sandbox Code Playgroud)

现在每个请求都有正确的django CSRF令牌.在我看来,这比在每个请求上手动放置令牌更正确,因为它使用来自两个框架(django和angularJS)的内置系统.


Pra*_*kar 7

你不能这样打电话:

$http({
    method: 'POST',
    url: url,
    data: xsrf,
    headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})
Run Code Online (Sandbox Code Playgroud)

data可不管你要传递,然后只是追加&{{csrf_token}}了这一点.

在您的资源中params:{},尝试csrfmiddlewaretoken:{{csrf_token}}在内部添加params

编辑:

您可以将数据传递给请求正文

item.$update({csrfmiddlewaretoken:{{csrf_token}}})
Run Code Online (Sandbox Code Playgroud)

和标题为

var csrf = '{{ csrf_token }}'; 
update:{method:'POST', headers: {'X-CSRFToken' : csrf }} 
Run Code Online (Sandbox Code Playgroud)

这是一个无证问题