角度,django 和 csrf

Posted

技术标签:

【中文标题】角度,django 和 csrf【英文标题】:angular, django and csrf 【发布时间】:2013-05-15 20:10:35 【问题描述】:

来自http://docs.angularjs.org/api/ng.$http,它说我们应该设置默认标头以包含令牌,所以我正在关注它。

我的代码是这样的

var myapp = angular.module('myapp', ['ngCookies', 'ui.bootstrap']).
    config(['$routeProvider', function($routeProvider, $httpProvider, $cookies)
        $routeProvider.
            when('/', 
                templateUrl: '/partials/home.html',
                controller: HomeCtrl
            ).
            when('/game/:gameId/shortlist/create',
                templateUrl: '/partials/create-shortlist.html',
                controller: CreateShortlistCtrl
            ).
            otherwise(redirectTo: '/');
    ]);

myapp.run(function($rootScope, $http, $cookies, $httpProvider)
    $http.get('/api/get-current-user').success(function(data)
        $rootScope.current_user = data;
        $rootScope.current_team = $rootScope.current_user.team;
    );
    $http.get('/api/get-current-season').success(function(data)
        $rootScope.current_season = data;
    );
    $rootScope.csrf_token = $cookies.csrftoken;
    console.log($httpProvider.defaults.headers.common);
    //$httpProvider.defaults.headers.post['X-CSRFToken'] = $cookies.csrftoken;
);

如您所见,我应用了多种方法,但无法使用 csrf 令牌设置标头。我遇到的两个错误是

未捕获的错误:未知提供程序:$httpProviderProvider

我做错了什么?

【问题讨论】:

【参考方案1】:

您只能在配置方法中使用$httpProvider。但问题是你不能在配置方法中使用$cookies。仅支持$cookiesProvider。 这在Module Loading & Dependencies 部分中有描述(有点)。

您可以按照angularjs.org docs 中的建议在运行时设置标头

因此,为了使您的示例正常工作,您可以执行以下操作:

var myapp = angular.module('myapp', ['ngCookies', 'ui.bootstrap']).
    config(['$routeProvider', function($routeProvider)
        $routeProvider.
            when('/', 
                templateUrl: '/partials/home.html',
                controller: HomeCtrl
            ).
            when('/game/:gameId/shortlist/create',
                templateUrl: '/partials/create-shortlist.html',
                controller: CreateShortlistCtrl
            ).
            otherwise(redirectTo: '/');
    ]);

myapp.run(function($rootScope, $http, $cookies)
    // set the CSRF token here
    $http.defaults.headers.post['X-CSRFToken'] = $cookies.csrftoken;

    $http.get('/api/get-current-user').success(function(data)
        $rootScope.current_user = data;
        $rootScope.current_team = $rootScope.current_user.team;
    );
    $http.get('/api/get-current-season').success(function(data)
        $rootScope.current_season = data;
    );
);

别忘了在你的 html 文件中包含 angular-cookies.js 文件!

【讨论】:

【参考方案2】:

如果您使用 AngularJS 1.1.3 或更新版本,您可以使用xsrfHeaderNamexsrfCookieName

var myapp = angular.module('myapp', ['ngCookies', 'ui.bootstrap']).
  config(['$routeProvider', function($routeProvider, $httpProvider, $cookies)
    $httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
    $httpProvider.defaults.xsrfCookieName = 'csrftoken';
    ...

请参阅 1.1.3 文档中的 $location。

【讨论】:

更好的方法。因为它通过了量角器的单元/e2e 测试【参考方案3】:

这是一个小库,可以让这更简单https://github.com/pasupulaphani/angular-csrf-cross-domain

【讨论】:

以上是关于角度,django 和 csrf的主要内容,如果未能解决你的问题,请参考以下文章

使用 CSRF_COOKIE_HTTPONLY 将 Django CSRF 令牌传递给 Angular

使用双重提交 cookie 的角度 SPA 中的 CSRF 保护

角度中的 CSRF 令牌与 Laravel 5 不同

角度注销后无法验证 CSRF 令牌的真实性

从Java代码实现角度探讨CSRF(采用全局的token)

Rails CSRF 保护与单页应用程序(反应,角度,余烬)