简体   繁体   English

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

[英]Express.js and Angular - authentication and login session

I'm using expressjs and angularjs for an app. 我正在为应用程序使用expressjs和angularjs。 Basically, expressjs just returns one .html that has an angular single-page-application. 基本上,expressjs仅返回一个具有角单页应用程序的.html。 All routing is done with angularjs, and expressjs just exposes some web services (GET, POST). 所有路由都使用angularjs完成,而expressjs仅公开一些Web服务(GET,POST)。

So, if I'd do just a regular expressjs app, I'd use passportjs and store user in session on server-side that'd be it. 因此,如果我只做一个常规的expressjs应用程序,那我会使用passportjsjs并将用户存储在服务器端的会话中。 When user tries to access /admin pages, I'd use passport middleware to check if route is allowed and so forth. 当用户尝试访问/ admin页面时,我将使用通行证中间件来检查是否允许路由等。 Plain and simple. 干净利落。

But with angular, all routing is done on client side - even evaluating if user is logged in. Now, of course, a lot has been written about this, but almost all solutions store any kind of token key in localStorage or angular's $cookie . 但是使用angular时,所有路由都在客户端完成,甚至可以评估用户是否登录。现在,当然,已经写了很多有关此的内容,但是几乎所有解决方案都在localStorage或angular的$cookie存储了任何种类的令牌密钥。 Now I'm wondering - is that safe? 现在我想知道-这样安全吗?

If anyone would ran such an application on a public computer, and forgot to logout, anyone would be able to look at the localStorage or angular's $cookie and get the token, right? 如果有人在公用计算机上运行了这样的应用程序而忘记了注销,那么任何人都可以查看localStorage或angular的$cookie并获得令牌,对吗?

So what is the theoretical process of implementing a safe authentication on client side, using angularjs? 那么,使用angularjs在客户端实施安全身份验证的理论过程是什么?

Quote: 引用:

So, if I'd do just a regular expressjs app, I'd use passportjs and store user in session on server-side that'd be it. 因此,如果我只做一个常规的expressjs应用程序,那我会使用passportjsjs并将用户存储在服务器端的会话中。

While the session data is stored on the server, the session identifier is stored on the client in a cookie. 会话数据存储在服务器上时,会话标识符以cookie的形式存储在客户端上。 If the cookie is stolen (such as in the public computer example), then the session can be used by someone else. 如果cookie被盗(例如在公共计算机示例中),则其他人可以使用该会话。 Client-side applications CAN use the cookie-session-identifier scheme. 客户端应用程序可以使用cookie-session-identifier方案。 When Angular makes XHR requests of your server, it will supply the cookie. 当Angular向您的服务器发出XHR请求时,它将提供cookie。

As you've seen, JSON Web Tokens (JWTs) have emerged as a new scheme. 如您所见,JSON Web令牌(JWT)已作为一种新方案出现。 They replace the session identifier, but not the cookie. 它们代替了会话标识符,而不是cookie。 You may see local storage being used instead, but this is not safe. 您可能会看到使用本地存储来代替,但这是不安全的。 Cookies are in fact the most secure place to store an authentication token, if you set the HttpOnly; Secure 实际上,如果设置了HttpOnly; Secure ,则Cookies是最安全的存储身份验证令牌的位置HttpOnly; Secure HttpOnly; Secure flags. HttpOnly; Secure标志。 This prevents the JS environment from reading the cookie, and prevents the browser from sending it to the server over non-secure channels. 这样可以防止JS环境读取cookie,并防止浏览器通过非安全通道将其发送到服务器。

I've written about JWTs and Angular apps at length, in these two articles: 我在这两篇文章中详细介绍了JWT和Angular应用:

Build Secure User Interfaces Using JSON Web Tokens (JWTs) 使用JSON Web令牌(JWT)构建安全的用户界面

Token Based Authentication for Single Page Apps (SPAs) 单页应用程序(SPA)的基于令牌的身份验证

If you're concerned about public computers, you have to avoid storing the token altogether. 如果您担心公用计算机,则必须避免完全存储令牌。 This means retaining the token in javascript memory, and supplying it via HTTP headers (typically Authorization: Bearer <access_tken> ). 这意味着将令牌保留在javascript内存中,并通过HTTP标头提供(通常是Authorization: Bearer <access_tken> )。 As soon as the tab is closed, the token is lost and the session is dead. 选项卡关闭后,令牌将丢失并且会话将终止。 Of course that requires the user to close the tab, so you can take it a step further and set a very low “time to idle” on your token, such as five minutes. 当然,这需要用户关闭选项卡,因此您可以更进一步,并为令牌设置非常低的“空闲时间”,例如五分钟。 If the user does not use the token within five minutes, it is considered in valid and they have to login again. 如果用户在五分钟内未使用令牌,则认为该令牌有效,因此他们必须再次登录。

PS I work at Stormpath and we have a user management service which makes it incredibly easy to add authentication to your Angular apps. PS我在Stormpath工作,我们有一个用户管理服务,使您可以轻松地向Angular应用添加身份验证。 You can read about it in our AngularJS Guide 您可以在《 AngularJS指南》中阅读有关它的信息。

I have done this by create an Angular Service called MyAuthentication which presents the methods 我通过创建一个名为MyAuthentication的Angular服务来完成此任务,该服务提供了方法

  • Authenticate(un, pwd) 验证(un,pwd)
  • Logout() 登出()

In order to get proper separation I have a separate user proxy which makes my user HTTP requests. 为了获得适当的分离,我有一个单独的用户代理,该代理发出我的用户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)
                }
            });
        }

    }

})

The user object stays in memory the entire time... Then entitlement could look something like this: 用户对象将一直保留在内存中...然后,权限可能看起来像这样:

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



   this.isEntitled = function(feature)  {

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

    }

})

AND on the server I am still using Passport. 并且在服务器上,我仍在使用Passport。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM