web-dev-qa-db-ja.com

POSTおよびAngularJSを使用してDjangoリクエスト(CSRFトークンを含む)を作成する方法

このPOSTビューにangular.jsを使用して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)

したがって、このリソースを作成しました。

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'}
    });
});

コントローラーでgetメソッドを呼び出すと正常に動作します。 URLは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!'});  
    });
}

Update/POSTメソッドの実行に関する問題に直面している間。

item.$update();

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'),

の代わりに

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

末尾にスラッシュを付けずに回避策を使用すると、403(禁止)ステータスコードが表示されます。これは、おそらく [〜#〜] csrf [〜#〜] トークンをPOST request。したがって、私の質問は、CSRFトークンをPOST angularによって作成されたリクエストに渡す方法を教えてください。

ヘッダーを介してcsrfトークンを渡す this アプローチについて知っていますが、投稿リクエストの本文にトークンを追加する可能性を探しています、推奨通り ここ 。 angularでpostリクエストの本文にデータを追加することは可能ですか?

追加の読みとして、リソースに関するこれらの議論、削除された末尾のスラッシュ、およびリソースが現在持っている制限 disc1 および disc2 を見ることができます。議論の1つで、著者の1人は現在リソースを使用せず、代わりに this アプローチを使用することを推奨しています。

23
Thomas Kremmel

次のような電話をかけることはできません:

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

dataは、渡したいものにすることができ、それに&{{csrf_token}}を追加するだけです。

リソースparams:{}で、params内にcsrfmiddlewaretoken:{{csrf_token}}を追加してみてください

編集:

あなたはリクエストボディにデータを渡すことができます

item.$update({csrfmiddlewaretoken:{{csrf_token}}})

ヘッダーとして

var csrf = '{{ csrf_token }}'; 
update:{method:'POST', headers: {'X-CSRFToken' : csrf }} 

文書化されていません issue

7

私はこれが1年以上前のものであることを知っていますが、誰かが同じ問題に遭遇した場合、angular JSにはすでにCSRF Coo​​kieフェッチメカニズム(AngularJSのバージョン1.1.5以降)があり、 angular Djangoが使用するCookieの名前と、サーバーとの通信に使用するHTTPヘッダーも教えてください。

そのためにモジュール構成を使用します。

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

これで、すべてのリクエストが正しいDjango CSRFトークンになります。私の意見では、両方のフレームワーク(DjangoとDjangoの組み込みシステムを使用しているため、手動でトークンを配置するよりもはるかに正しいです。 angularJS)。

39
Anoyz

最近のangularjsバージョンでは、解決策が機能していません。だから私は以下を試しました

  • まず、マークアップにDjangoタグ{%csrf_token%}を追加します。

  • アプリの構成ファイルに$ httpインスペクターを追加する

angular.module('myApp').config(function ( $httpProvider) {
   $httpProvider.interceptors.Push('myHttpRequestInterceptor'); 
});
  • 次に、そのmyHttpRequestInterceptorを定義します
angular.module("myApp").factory('myHttpRequestInterceptor', function ( ) {

   return {
             config.headers = { 
              'X-CSRFToken': $('input[name=csrfmiddlewaretoken]').val() } 
             } 
   return config; 
  }}; 
});

x-CSRFTokenをすべてのangularリクエストに追加します

最後に、Djangoミドルウェア "Django.middleware.csrf.CsrfViewMiddleware '"を追加する必要があります。これにより、CSRFの問題が解決します

1
mdimran

私はこれを使います:

Djangoビュー:

@csrf_protect
def index(request):
    #Set cstf-token cookie for rendered template
    return render_to_response('index.html', RequestContext(request))

App.jsの場合:

(function(A) {
    "use strict";
    A.module('DesktopApplication', 'ngCookies' ]).config(function($interpolateProvider, $resourceProvider) {
        //I use {$ and $} as Angular directives
        $interpolateProvider.startSymbol('{$');
        $interpolateProvider.endSymbol('$}');
        //Without this Django not processed urls without trailing slash
        $resourceProvider.defaults.stripTrailingSlashes = false; 
    }).run(function($http, $cookies) {
        //Set csrf-kookie for every request
        $http.defaults.headers.post['X-CSRFToken'] = $cookies.csrftoken;
        $http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
    });
}(this.angular));

正しいリクエストを送信するには、オブジェクトをparam-formに変換する必要があります。

$http.post('/items/add/', $.param({name: 'Foo'}));//Here $ is jQuery
0
Dunaevsky Maxim
var app = angular.module('angularFoo', ....

app.config(["$httpProvider", function(provider) {
  provider.defaults.headers.common['X-CSRFToken'] = '<<csrftoken value from template or cookie>>';
}])
0
Serge K.