2015-05-31 32 views
1

我正在爲應用程序使用expressjs和angularjs。基本上,expressjs只是返回一個具有角度單頁面應用程序的.html。所有路由都是使用angularjs完成的,而expressjs只是公開了一些Web服務(GET,POST)。Express.js和Angular - 身份驗證和登錄會話

因此,如果我只是做一個普通的expressjs應用程序,我會使用passportjs並將用戶存儲在服務器端的會話中。當用戶嘗試訪問/管理頁面時,我會使用護照中間件來檢查是否允許路由等等。乾淨利落。

但隨着角度,所有的路由是在客戶端完成的 - 如果用戶登錄,即使評估現在,當然,很多人都寫了這一點,但幾乎所有的解決方案存儲任何類型的令牌密鑰的localStorage或angular的$cookie。現在我想知道 - 安全嗎?

如果有人會在公用計算機上運行這樣的應用程序,並且忘記註銷,任何人都可以查看localStorage或angular的$cookie並獲取令牌,對嗎?

那麼使用angularjs在客戶端實現安全認證的理論過程是什麼?

回答

0

我已經做到了這一點通過創建一個名爲MyAuthentication角度服務呈現方法

  • 進行身份驗證(聯合國,PWD)
  • 退出()

爲了得到適當的分離我有一個單獨的用戶代理,它使我的用戶HTTP請求。

angular.module('myNgApplication').service('MyAuthentication', function ($rootScope, $cookies, $log, UserProxy) { 

    var self = this; 
    self.user = null ; 

    (function(){ 
     UserProxy.retrieveSession().then(function(authResponse){ 
      self.user = authResponse 
     }, function() { 
      self.user = null 
     }) 
    }).call(this) 

    this.isLoggedIn = function() { 
     return self.user != null ; 
    } 

    this.login = function (email, password) { 
     return UserProxy.login(email, password).then(function(authResponse){ 
      self.user = authResponse 
      return self.user 
     }) 
    } 

    this.logout = function() { 
     return UserProxy.logout().then(function(response){ 
      self.user = null ; 
      return response 
     }) 
    } 

    // this is never used externally. because the HTTP request to gte the user may be in progress when this is called and therefore self.user is null 
    this.getUser = function() { 
     return self.user 
    } 

    this.bootstrapUser = function(callback){ 
     if(self.isLoggedIn()){ 
      callback(self.user) 
     } 
     else { 
      $rootScope.$watch(self.getUser, function(newUser, oldUser) { 
       if(newUser != oldUser) { 
        callback(self.user) 
       } 
      }); 
     } 

    } 

}) 

用戶對象在內存中停留的整個時間...然後授權可能是這個樣子:

angular.module('myNgApplication').service('MyEntitlments', function (MyAuthentication) { 



    this.isEntitled = function(feature) { 

     return MyAuthentication.bootstrapUser(function(user){ 
      // check users role and feature    
      return true || false 
     }) 

    } 

}) 

,我仍然使用Passport的服務器上。

+0

好的,所以這不是存儲在cookie或localstorage?但是如果用戶關閉瀏覽器並返回頁面會發生什麼 - 他必須再次登錄,對吧? – uglycode

+0

好吧,是的。你不能兩面都有。您可以做的另一件事是添加一個cookie來標識服務器上的會話。用戶cookie中唯一的東西是會話ID。 MyAuthentication服務中的自我調用功能試圖檢索會話...所以你可以在那裏工作。 – akaphenom

+0

現實情況是,您將需要存儲本地的東西,或者要求它們在關閉瀏覽器時重新登錄。如果你存儲了本地的東西,那麼你最好儘可能少地存儲。 – akaphenom

3

報價:

所以,如果我做的只是一個普通的expressjs應用程序,我會使用passportjs和存儲用戶在會議服務器端那將會是它。

雖然會話數據存儲在服務器上,但會話標識符存儲在客戶端的Cookie中。如果cookie被盜(例如在公共計算機示例中),則該會話可以被其他人使用。客戶端應用程序可以使用cookie會話標識符方案。當Angular向您的服務器發出XHR請求時,它將提供cookie。如你所見,JSON Web Tokens(JWT)已經成爲一種新的方案。他們替換會話標識符,但不是cookie。您可能會看到正在使用本地存儲,但這不安全。如果您設置HttpOnly; Secure標誌,Cookie實際上是存儲身份驗證令牌的最安全的地方。這會阻止JS環境讀取cookie,並阻止瀏覽器通過非安全通道將其發送到服務器。

我已經寫JWTs和長角的應用程序,在這兩篇文章:

Build Secure User Interfaces Using JSON Web Tokens (JWTs)

Token Based Authentication for Single Page Apps (SPAs)

如果你關心的公共電腦,你必須避免存儲令牌。這意味着將令牌保留在JavaScript內存中,並通過HTTP頭提供(通常爲Authorization: Bearer <access_tken>)。一旦選項卡關閉,令牌就會丟失,會話就會失效。當然,這要求用戶關閉標籤,以便您可以更進一步並在令牌上設置非常低的「閒置時間」,例如5分鐘。如果用戶在五分鐘內未使用該令牌,則認爲該令牌有效,並且必須再次登錄。

P.S.我在Stormpath工作,我們有一個用戶管理服務,這使得向Angular應用程序添加身份驗證非常容易。你可以在我們的AngularJS Guide