WedX - журнал о программировании и компьютерных науках

Обработка токенов CSRF/XSRF с интерфейсом Angular и серверной частью Drupal 7

Я занимаюсь созданием нового интерфейса AngularJS для веб-сайта Drupal 7. Это использует модуль Services с аутентификацией на основе сеанса в двух доменах с использованием CORS. Я могу пройти аутентификацию с помощью Drupal, получить пользовательский объект и данные сеанса, а затем получить токен CSRF из модуля служб. У меня проблемы с настройкой всего этого в заголовке, чтобы последующие запросы аутентифицировались. Я понимаю общую концепцию, но новичок как в AngularJS, так и в предотвращении атак CSRF.

Из того, что я узнал об этой настройке с AngularJS и RubyOnRails, между платформами могут быть несоответствия в отношении того, как называется токен и как он обрабатывается. Также кажется, что есть ряд предложений о том, как установить этот токен в заголовке. Однако у меня возникли проблемы с поиском надежного примера того, как заставить эти платформы говорить на одном языке.

Единственное, что я делаю с моим $httpProvider в app.js, это:

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 = 'https://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 = 'https://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');
            }
        });
      };

Ответы:


1

Решение связано с тем, как файлы cookie должны быть установлены, а затем переданы через последующие запросы. Попытки установить их вручную не увенчались успехом, но решение оказалось проще, чем я ожидал. Каждый вызов $http должен устанавливать параметры:

withCredentials: true

Еще одно изменение, которое я внес, заключалось в использовании термина CSRF вместо XSRF, чтобы соответствовать Drupal. Я не использовал какие-либо встроенные функции CSRF AngularJS.

16.08.2013
  • Прошло много времени с тех пор, как этот ответ был опубликован. но есть ли шанс, что вы можете привести пример того, как вы делаете дальнейший последующий запрос? Я борюсь с этим. Я могу войти и сохранить все данные о сеансе пользователя, а также токен (отправляя обратно cookie и X-CSRF-Token). но каждый следующий запрос, который я делаю в drupal, возвращает ошибку «пользователь не вошел в систему». 08.08.2016

  • 2
            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{}, в которой я определяю новый заголовок и называю его X-CSRF-Token, и получаю значение из DOM сгенерированного (на стороне сервера) html или php. Не рекомендуется также запрашивать токен csrf с сервера. Злоумышленник может каким-то образом запросить и его. Поскольку вы сохраняете его как файл cookie. Злоумышленник может украсть файл cookie! Нет необходимости сохранять его в файле cookie! отправьте токен с заголовком и прочитайте его на стороне сервера, чтобы он соответствовал!

    и для нескольких вкладок одной и той же страницы. Я использую один и тот же токен на протяжении всего сеанса. Регенерировать только при входе в систему, выходе из системы и изменении основных настроек сайта или пользователя.

    28.05.2014

    3

    Существует отличная библиотека под названием ng-drupal-7-services. Если вы используете это в своем проекте, он автоматически решает аутентификацию/повторную аутентификацию и создание файла/узла, и вы можете сосредоточиться на важных вещах в вашем проекте.

    Итак, аутентификация решается следующим образом:

    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

    12.03.2016

    4

    Да, каждая платформа имеет собственное соглашение по именованию своих токенов.

    Вот небольшая библиотека, собранная в надежде упростить ее использование на разных платформах. Это позволит вам использовать имена наборов и может использоваться во всех запросах. Он также работает для междоменных запросов.

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

    05.01.2015
    Новые материалы

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..


    Для любых предложений по сайту: [email protected]