Node.js + express.js +passport.js:在服务器重启之间保持身份验证

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10164312/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 15:32:39  来源:igfitidea点击:

Node.js + express.js + passport.js : stay authenticated between server restart

node.jsexpress

提问by Arnaud Rinquin

I use passport.js to handle auth on my nodejs + express.js application. I setup a LocalStrategy to take users from mongodb

我使用passport.js 在我的nodejs + express.js 应用程序上处理身份验证。我设置了一个 LocalStrategy 来从 mongodb 中获取用户

My problems is that users have to re-authenticate when I restart my node server. This is a problem as I am actively developing it and don't wan't to login at every restart... (+ I use node supervisor)

我的问题是当我重新启动我的节点服务器时用户必须重新进行身份验证。这是一个问题,因为我正在积极开发它并且不想在每次重启时登录......(+我使用节点主管)

Here is my app setup :

这是我的应用程序设置:

app.configure(function(){
    app.use('/static', express.static(__dirname + '/static'));
    app.use(express.bodyParser());
    app.use(express.methodOverride());
    app.use(express.cookieParser());
    app.use(express.session({secret:'something'}));
    app.use(passport.initialize());
    app.use(passport.session());
    app.use(app.router);
});

And session serializing setup :

和会话序列化设置:

passport.serializeUser(function(user, done) {
    done(null, user.email);
});

passport.deserializeUser(function(email, done) {
    User.findOne({email:email}, function(err, user) {
        done(err, user);
    });
});

I tried the solution given on a blog (removed the link as it does not exist any more) using connect-mongodb without success

我使用 connect-mongodb 尝试了博客上给出的解决方案(删除了链接,因为它不再存在)但没有成功

app.use(express.session({
    secret:'something else',
    cookie: {maxAge: 60000 * 60 * 24 * 30}, // 30 days
        store: MongoDBStore({
        db: mongoose.connection.db
    })
}));

EDITadditional problem : only one connection should be made (use of one connexion limited mongohq free service)

编辑附加问题:只应建立一个连接(使用一个连接受限的 mongohq 免费服务)

EDIT 2solution (as an edition as I my reputation is to low to answer my question by now

EDIT 2解决方案(作为一个版本,因为我现在的声誉很低,无法回答我的问题

Here is the solution I finally found, using mongoose initiated connection

这是我最终找到的解决方案,使用猫鼬发起的连接

app.use(express.session({
    secret:'awesome unicorns',
    maxAge: new Date(Date.now() + 3600000),
    store: new MongoStore(
        {db:mongoose.connection.db},
        function(err){
            console.log(err || 'connect-mongodb setup ok');
        })
}));

采纳答案by Arnaud Rinquin

There's an opensource called connect-mongothat does exactly what you need - persists the session data in mongodb

有一个名为connect-mongo的开源软件,它可以完全满足您的需求 - 将会话数据保存在 mongodb 中

usage example (with a reuse of mongooseopened connection) :

使用示例(重用mongoose打开的连接):

var session = require('express-session');
var MongoStore = require('connect-mongo')(session);
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/sess');
app.use(express.session({
    secret:'secret',
    maxAge: new Date(Date.now() + 3600000),
    store: new MongoStore(
    // Following lines of code doesn't work
    // with the connect-mongo version 1.2.1(2016-06-20).
    //    {db:mongoose.connection.db},
    //    function(err){
    //        console.log(err || 'connect-mongodb setup ok');
    //   }
    {mongooseConnection:mongoose.connection}
    )        
}));

you can read more about it here: https://github.com/kcbanner/connect-mongo

你可以在这里阅读更多关于它的信息:https: //github.com/kcbanner/connect-mongo

回答by toxinlabs

i use connect-mongo like so:

我像这样使用connect-mongo:

var MongoStore = require('connect-mongo');

var sess_conf = {
  db: {
    db: mydb,
    host: localhost,
    collection: 'usersessions' // optional, default: sessions
  },
  secret: 'ioudrhgowiehgio'
};

 app.use(express.session({
    secret: sess_conf.secret,
    maxAge: new Date(Date.now() + 3600000),
    store: new MongoStore(sess_conf.db)
  }));


[...]

// Initialize Passport!  Also use passport.session() middleware, to support
  // persistent login sessions (recommended).
  app.use(passport.initialize());
  app.use(passport.session());

回答by freakish

This is because you use MemoryStore (default) for sessions. Look at this code from memory.js (part of Connect framework):

这是因为您对会话使用 MemoryStore(默认)。查看 memory.js 中的这段代码(Connect 框架的一部分):

var MemoryStore = module.exports = function MemoryStore() {
  this.sessions = {};
};

and this snippet from session.js (Express)

以及 session.js (Express) 中的这个片段

function session(options){
    /* some code */
    , store = options.store || new MemoryStore
    /* some code */
}

Now you should understand that every server restart resets the MemoryStore. In order to keep the data you have to use some other session store. You can even write your own (shouldn't be too difficult), although Redis (see this library) might be a good choice (and it is well supported by Express).

现在您应该明白每次服务器重启都会重置 MemoryStore。为了保留数据,您必须使用其他一些会话存储。您甚至可以自己编写(应该不会太难),尽管 Redis(请参阅此库)可能是一个不错的选择(并且 Express 很好地支持它)。

// EDIT

// 编辑

According to the Connect documentationit is enough for you if you implement get, setand destroymethods. The following code should work:

根据Connect 文档,如果您实现get,setdestroy方法就足够了。以下代码应该可以工作:

customStore = {
    get : function(sid, callback) {
        // custom code, for example calling MongoDb
    },
    set : function(sid, session, callback) {
        // custom code
    },
    destroy : function(sid, callback) {
        // custom code
    }
}    

app.use(express.session({
    store: customStore
}));

You just need to implement calling MongoDb (or any other Db although I still recommend using nonpermament one like Redis) for storing session data. Also read the source code of other implementations to grab the idea.

您只需要实现调用 MongoDb(或任何其他 Db,尽管我仍然建议使用像 Redis 这样的非永久性数据库)来存储会话数据。另请阅读其他实现的源代码以获取想法。

回答by harryrobbins

This is probably obvious to experienced node users but it caught me out:

这对于有经验的节点用户来说可能很明显,但它让我发现了:

You need to configure the node session - e.g.

您需要配置节点会话 - 例如

app.use(session({secret: "this_is_secret", store: ...}));

beforeinitializing the passport session - e.g.

初始化护照会话之前- 例如

app.use(passport.initialize());
app.use(passport.session());

If you call passport.session() first it won't work (and it won't warn you). I thought the problem was with the serialize/deserialize user functions and wasted hours.

如果您先调用passport.session() 它将不起作用(并且不会警告您)。我认为问题在于序列化/反序列化用户功能和浪费了时间。

回答by Kevin Suttle

What I ended up doing:

我最终做了什么:

var expressSession = require('express-session');
var redisClient = require('redis').createClient();
var RedisStore = require('connect-redis')(expressSession);
...
app.use(expressSession({
    resave: true,
    saveUninitialized: true,
    key: config.session.key,
    secret: config.session.secret,
    store: new RedisStore({
        client: redisClient,
        host: config.db.host,
        port: config.db.port,
        prefix: 'my-app_',
        disableTTL: true
    })
}));

Works for me.

对我来说有效。

回答by James Brian Lago

You need to change the store you are using for your sessions. The default one 'MemoryStore' does not continue to store the session when you're application stops. Check out express-session on github to find out more about what other stores there are like the mongo one. (Can't remember the name)

您需要更改用于会话的商店。当您的应用程序停止时,默认的“MemoryStore”不会继续存储会话。查看 github 上的 express-session 以了解更多有关其他商店的信息,例如 mongo 商店。(不记得名字了)

回答by arg20

I'm using mongoose, I tried the code presented in the answers above and it didn't work for me. I got this error when I did:

我正在使用猫鼬,我尝试了上面答案中提供的代码,但它对我不起作用。我这样做时遇到了这个错误:

Error: db object already connecting, open cannot be called multiple times

However, this works for me:

但是,这对我有用:

app.use(express.session({
    secret:'secret',
    maxAge: new Date(Date.now() + 3600000),
    store: new MongoStore({mongoose_connection:mongoose.connection})
}))

Note: If you don't have MongoStore for whatever reason, you need to do:

注意:如果您由于某种原因没有 MongoStore,则需要执行以下操作:

npm install connect-mongo --save

then:

然后:

var MongoStore = require('connect-mongo')(express)