Express.js和Angular - 身份验证和登录会话

时间:2015-05-31 09:47:24

标签: javascript angularjs node.js express

我正在为应用使用expressjs和angularjs。基本上,expressjs只返回一个.html,它有一个有角度的单页面应用程序。所有路由都是使用angularjs完成的,而expressjs只是暴露了一些Web服务(GET,POST)。

所以,如果我只做一个普通的expressjs应用程序,我会使用passportjs并将用户存储在服务器端的会话中。当用户尝试访问/管理页面时,我会使用护照中间件来检查是否允许路由等等。简单明了。

但是对于angular,所有路由都在客户端完成 - 甚至评估用户是否已登录。当然,现在已经写了很多关于此的内容,但几乎所有解决方案都存储了{{1中的任何类型的令牌密钥}}或角度的localStorage。现在我想知道 - 这样安全吗?

如果有人在公共计算机上运行此类应用程序,并且忘记退出,则任何人都可以查看$cookie或角度localStorage并获取令牌,正确?

那么使用angularjs在客户端实现安全认证的理论过程是什么?

2 个答案:

答案 0 :(得分:3)

引用:

  

所以,如果我只做一个普通的expressjs应用程序,我会使用passportjs并将用户存储在服务器端的会话中。

会话数据存储在服务器上时,会话标识符以cookie的形式存储在客户端上。如果cookie被盗(例如在公共计算机示例中),那么该会话可以被其他人使用。客户端应用程序可以使用cookie-session-identifier方案。当Angular发出服务器的XHR请求时,它将提供cookie。

正如您所见,JSON Web令牌(JWT)已经成为一种新方案。它们替换会话标识符,但不替换cookie。您可能会看到使用本地存储,但这不安全。如果您设置HttpOnly; Secure标志,Cookie实际上是存储身份验证令牌的最安全的地方。这可以防止JS环境读取cookie,并阻止浏览器通过非安全通道将其发送到服务器。

我在这两篇文章中详细介绍了JWT和Angular应用程序:

Build Secure User Interfaces Using JSON Web Tokens (JWTs)

Token Based Authentication for Single Page Apps (SPAs)

如果您担心公共计算机,则必须完全避免存储令牌。这意味着将令牌保留在javascript内存中,并通过HTTP头(通常为Authorization: Bearer <access_tken>)提供。选项卡一旦关闭,令牌就会丢失并且会话已经死亡。当然,这需要用户关闭选项卡,因此您可以更进一步,并在令牌上设置非常低的“空闲时间”,例如五分钟。如果用户在五分钟内未使用该令牌,则认为该用户有效并且必须再次登录。

P.S。我在Stormpath工作,我们有一个用户管理服务,可以非常轻松地为Angular应用添加身份验证。您可以在我们的AngularJS Guide

中了解相关信息

答案 1 :(得分:0)

我通过创建名为MyAuthentication的Angular服务来完成此操作,该服务提供了方法

  • 验证(un,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。