2013-07-29 67 views
4

我正在爲Drupal 7網站構建新的AngularJS前端。這是通過基於會話的認證使用服務模塊,使用CORS跨兩個域。我可以使用Drupal進行身份驗證,檢索用戶對象和會話數據,然後從服務模塊獲取CSRF令牌。我遇到的麻煩是將所有這些設置在標題中,以便後續請求得到驗證。我瞭解整體概念,但對AngularJS和防止CSRF攻擊都是新手。使用Angular前端和Drupal 7後端處理CSRF/XSRF標記

從我所瞭解的有關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'); 
      } 
     }); 
     }; 

回答

3

的解決方案必須做如何設置cookie,然後通過後續請求。嘗試手動設置它們並不好,但解決方案比我預期的要簡單。每個$ HTTP調用需要設置的選項:

withCredentials: true 

我做的另一個改變是使用術語CSRF而不是XSRF,是使用Drupal一致。我沒有使用任何內置的AngularJS CSRF功能。

+0

對其進行了長久以來這個答案被張貼。但是有沒有機會舉例說明你如何進一步提出後續請求?我正在努力與此。我可以登錄並存儲所有用戶會話詳細信息和令牌(發回cookie和X-CSRF-令牌)。但是我對drupal做出的每一個進一步的請求都返回'user is not logged in'錯誤。 –

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

       } 
      }); 
     } 

既然已經是這個話題的一年了!不確定仍然遇到同樣的問題,但對於那些來尋找答案的人是我如何處理它! 注意頭{}部分我定義了一個新頭,並將其稱爲X-CSRF-Token,並從(serverside)的DOM中獲取生成html或php的值。同時向服務器請求csrf令牌也不是一個好習慣.Cuz攻擊者也可以以某種方式請求這一點。既然你把它保存爲一個cookie。攻擊者可以竊取cookie!無需將其保存在cookie中!發送帶有標題的令牌並在服務器端讀取它以匹配它!

和多頁同一頁面問題。我在整個會話中使用相同的標記。 只有在登錄,註銷和更改主要站點或用戶設置時纔會重新生成。

0

是的,每個平臺都有自己的約定來命名它們的令牌。

這是一個小型的lib,放在一起希望能夠很容易地在不同的平臺上使用。這將允許您使用集名稱並可用於所有請求。它也適用於跨域請求。

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

2

有一個偉大的圖書館callse 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'; 
 

 

 
\t 
 

 
AuthenticationHttpInterceptor.$inject = [ '$injector']; 
 

 
function AuthenticationHttpInterceptor($injector) { 
 
\t 
 
    \t 
 
    var intercepter = { 
 
    \t request \t : 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; 
 
    }; 
 
\t

也有一些種類的廚房水槽的這個項目在這裏:Drupal-API-Explorer