【问题标题】:Handling CSRF/XSRF tokens with Angular frontend and Drupal 7 backend使用 Angular 前端和 Drupal 7 后端处理 CSRF/XSRF 令牌
【发布时间】:2013-07-29 17:52:21
【问题描述】:

我正在为 Drupal 7 网站构建新的 AngularJS 前端。这是使用带有基于会话的身份验证的服务模块,跨两个使用 CORS 的域。我能够使用 Drupal 进行身份验证,检索用户对象和会话数据,然后从服务模块获取 CSRF 令牌。我遇到的问题是在标头中设置所有这些,以便对后续请求进行身份验证。我了解整体概念,但对 AngularJS 和防止 CSRF 攻击都是新手。

根据我收集到的关于 AngularJS 和 RubyOnRails 设置的信息,平台之间在令牌命名和处理方式方面可能存在不一致。似乎还有一些关于如何在标题中设置此标记的建议。但是,我很难找到一个可靠的例子来说明如何让这些平台使用相同的语言。

我在 app.js 中使用 $httpProvider 做的唯一事情是:

delete $httpProvider.defaults.headers.common['X-Requested-With'];

登录控制器,在 controller.js 中:

  .controller('LoginCtrl', ['$scope', '$http', '$cookies', 'SessionService', function($scope, $http, $cookies, SessionService) {
    $scope.login = function(user) {
        //set login url and variables
        var url = 'http://mywebsite.com/service/default/user/login.json';
        var postDataString = 'name=' + encodeURIComponent(user.username) + '&pass=' + encodeURIComponent(user.password);

        $http({
            method: 'POST',
            url: url,
            data : postDataString,
            headers: {'Content-Type': 'application/x-www-form-urlencoded'}
        }).success(function (data, status, headers, config) {
            var sessId = data.sessid;
            var sessName = data.session_name;
            $cookies[sessName] = sessId;

            var xsrfUrl = 'http://mywebsite.com/services/session/token';
            $http({
                method: 'GET',
                url: xsrfUrl
            }).success(function (data, status, headers, config) {
                $cookies["XSRF-TOKEN"] = data;
                SessionService.setUserAuthenticated(true);
            }).error(function (data, status, headers, config) {
                console.log('error loading xsrf/csrf');
            });
        }).error(function (data, status, headers, config) {
            if(data) {
                console.log(data);
                var msgText = data.join("\n");
                alert(msgText);
            } else {
                alert('Unable to login');
            }
        });
      };

【问题讨论】:

    标签: rest drupal angularjs drupal-7 csrf


    【解决方案1】:

    有一个很棒的库调用ng-drupal-7-services。如果您在项目中使用它,它可以解决框的身份验证/重新身份验证和文件/节点创建 aut,您可以专注于项目中的重要内容。

    所以身份验证是这样解决的:

    function login(loginData) {
      //UserResource ahndles all requeste of the services 3.x user resource.
      return UserResource
      .login(loginData)
      .success(function (responseData, status, headers, config) {
        setAuthenticationHeaders(responseData.token);
    
        setLastConnectTime(Date.now());
        setConnectionState((responseData.user.uid === 0)?false:true)
        setCookies(responseData.sessid, responseData.session_name);
        setCurrentUser(responseData.user);
    
        AuthenticationChannel.pubLoginConfirmed(responseData);
      })
      .error(function (responseError, status, headers, config) {
        AuthenticationChannel.pubLoginFailed(responseError);
      });
    
    };
    
    (function() {
    'use strict';
    
    
    	 
    
    AuthenticationHttpInterceptor.$inject = [ '$injector'];
    
    function AuthenticationHttpInterceptor($injector) {
    	
      	
        var intercepter = {
        	request 	: doRequestCongiguration,
        };
        
        return intercepter;
    
        function doRequestCongiguration (config) {
            var tokenHeaders = null;
     
            // Need to manually retrieve dependencies with $injector.invoke
            // because Authentication depends on $http, which doesn't exist during the
            // configuration phase (when we are setting up interceptors).
            // Using $injector.invoke ensures that we are provided with the
            // dependencies after they have been created.
            $injector.invoke(['AuthenticationService', function (AuthenticationService) {
                tokenHeaders = AuthenticationService.getAuthenticationHeaders();
                
            }]);
    
            //add headers_______________________
            
            //add Authorisation and X-CSRF-TOKEN if given
            if (tokenHeaders) {
                angular.extend(config.headers, tokenHeaders);
            }
            
            //add flags_________________________________________________
            
            //add withCredentials to every request
            //needed because we send cookies in our request headers
            config.withCredentials = true;
    
            return config;
        };
    	

    这里还有一些适合这个项目的厨房水槽:Drupal-API-Explorer

    【讨论】:

      【解决方案2】:

      是的,每个平台在命名令牌时都有自己的约定。

      这里是一个小库,希望能够使其易于在不同平台上使用。这将允许您使用集合名称,并且可以在所有请求中使用。它也适用于跨域请求。

      https://github.com/pasupulaphani/angular-csrf-cross-domain

      【讨论】:

        【解决方案3】:
                addItem: function(data)
                {
                    return $http.post('api/programs/'+$stateParams.id+'/workouts', {item:data},{
                        headers:
                        {
                            'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
                            'X-CSRF-Token': $('meta[name="xxtkn"]').attr('content')
        
                        }
                    });
                }
        

        因为这个话题已经一年了!不确定是否仍然遇到同样的问题,但对于那些来这里寻找答案的人来说,这就是我的处理方式! 注意 headers{} 部分,我定义了一个新的 header 并将其称为 X-CSRF-Token 并从(服务器端)生成的 html 或 php 的 DOM 中获取值。从服务器请求 csrf 令牌也不是一个好习惯。因为攻击者也可以通过某种方式请求它。由于您将其保存为cookie。攻击者可以窃取cookie!无需将其保存在 cookie 中!发送带有标头的令牌并在服务器端读取它以匹配它!

        对于同一页面的多选项卡问题。我在整个会话期间使用相同的令牌。 仅在登录、注销和更改主要站点或用户设置时重新生成。

        【讨论】:

          【解决方案4】:

          解决方案与如何设置 cookie 以及如何通过后续请求有关。尝试手动设置它们并不顺利,但解决方案比我预期的要简单。每个 $http 调用都需要设置选项:

          withCredentials: true
          

          我所做的另一个更改是使用术语 CSRF 而不是 XSRF,以与 Drupal 保持一致。我没有使用任何内置的 AngularJS CSRF 功能。

          【讨论】:

          • 这个答案发布已经很久了。但是你有没有机会举例说明你如何提出进一步的后续请求?我正在为此苦苦挣扎。我可以登录并存储所有用户会话详细信息以及令牌(发回 cookie 和 X-CSRF-Token)。但我对 drupal 提出的每一个进一步请求,它都会返回“用户未登录”错误。
          猜你喜欢
          • 2018-01-19
          • 2018-07-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-03-02
          • 1970-01-01
          • 1970-01-01
          • 2021-02-19
          相关资源
          最近更新 更多