Node.js + express.js + passport.js: permanezca autenticado entre el reinicio del servidor

Utilizo passport.js para manejar la autenticación en mi aplicación nodejs + express.js. Configuré una estrategia local para sacar a los usuarios de mongodb

Mi problema es que los usuarios deben volver a autenticarse cuando reinicio mi servidor de nodo . Este es un problema ya que lo estoy desarrollando activamente y no quiero iniciar sesión en cada reinicio …

Aquí está mi configuración de la aplicación:

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); }); 

Y la sesión de configuración de serialización:

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

Probé la solución dada en un blog (eliminé el enlace porque ya no existe) usando connect-mongodb sin éxito

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

EDITAR problema adicional: solo se debe hacer una conexión (uso de una conexión limitada mongohq servicio gratuito)

Solución EDIT 2 (como una edición, ya que mi reputación es demasiado baja para responder mi pregunta por ahora)

Aquí está la solución que finalmente encontré, utilizando una conexión iniciada por mongoose

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

Hay una fuente abierta llamada connect-mongo que hace exactamente lo que necesita: persiste los datos de la sesión en mongodb

Ejemplo de uso (con una reutilización de la conexión abierta 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} ) })); 

Puede leer más sobre esto aquí: https://github.com/kcbanner/connect-mongo

Yo uso connect-mongo como tal:

 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()); 

Esto se debe a que utiliza MemoryStore (predeterminado) para las sesiones. Mire este código desde memory.js (parte del marco de Connect):

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

y este fragmento de sesion.js (Express)

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

Ahora debe comprender que cada reinicio del servidor restablece el MemoryStore. Para mantener los datos, debe utilizar algún otro almacén de sesión. Incluso puede escribir el suyo propio (no debería ser demasiado difícil), aunque Redis (consulte esta biblioteca ) puede ser una buena opción (y está bien respaldado por Express).

// EDITAR

De acuerdo con la documentación de Connect , es suficiente si implementa los métodos de get , set y destroy . El siguiente código debería funcionar:

 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 })); 

Solo necesita implementar la llamada a MongoDb (o cualquier otra Db, aunque sigo recomendando el uso de un método no válido como Redis) para almacenar los datos de la sesión. También lea el código fuente de otras implementaciones para captar la idea.

Esto es probablemente obvio para los usuarios de nodo con experiencia, pero me sorprendió:

Debe configurar la sesión de nodo, por ejemplo,

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

antes de inicializar la sesión de pasaporte – por ejemplo

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

Si llama a passport.session () primero, no funcionará (y no le avisará). Pensé que el problema era con la serialización / deserialización de las funciones del usuario y las horas perdidas.

Estoy usando mongoose, probé el código presentado en las respuestas anteriores y no funcionó para mí. Recibí este error cuando lo hice:

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

Sin embargo, esto funciona para mí:

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

Nota: Si no tiene MongoStore por cualquier razón, debe hacer:

 npm install connect-mongo --save 

entonces:

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

Lo que acabé haciendo:

 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 }) })); 

Funciona para mi.

Necesitas cambiar la tienda que estás usando para tus sesiones. El predeterminado ‘MemoryStore’ no continúa almacenando la sesión cuando la aplicación se detiene. Echa un vistazo a express-session en github para obtener más información sobre qué otras tiendas hay como mongo. (No recuerdo el nombre)