76 votes

Node.js + express.js + passport.js : rester authentifié entre deux redémarrages du serveur

J'utilise passport.js pour gérer l'authentification sur mon application nodejs + express.js. J'ai configuré une LocalStrategy pour récupérer les utilisateurs de mongodb.

Mes problèmes sont les suivants Les utilisateurs doivent se ré-authentifier lorsque je redémarre mon serveur de nœuds. . C'est un problème car je le développe activement et je ne veux pas avoir à me connecter à chaque redémarrage... (+ j'utilise le superviseur de nœuds)

Voici la configuration de mon application :

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

Et configuration de la sérialisation des sessions :

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

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

J'ai essayé la solution donnée sur un blog (j'ai enlevé le lien car il n'existe plus) en utilisant connect-mongodb sans succès.

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

EDITAR problème supplémentaire : une seule connexion doit être établie (l'utilisation d'une seule connexion limite le service gratuit de mongohq)

EDIT 2 solution (comme une édition car ma réputation est trop faible pour répondre à ma question maintenant

Voici la solution que j'ai finalement trouvée, en utilisant la connexion initiée par la mangouste.

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

56voto

Arnaud Rinquin Points 2231

Voici la solution finale et complète utilisant connect-mongodb et réutilisant la connexion mongoose.

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

6voto

toxinlabs Points 345

J'utilise connect-mongo comme suit :

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

5voto

freakish Points 20067

Cela est dû au fait que vous utilisez MemoryStore (par défaut) pour les sessions. Regardez ce code provenant de memory.js (qui fait partie du cadre Connect) :

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

et cet extrait de session.js (Express)

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

Vous devez maintenant comprendre que chaque redémarrage du serveur réinitialise le MemoryStore. Afin de conserver les données, vous devez utiliser un autre magasin de session. Vous pouvez même écrire le vôtre (cela ne devrait pas être trop difficile), bien que Redis (cf. cette bibliothèque ) pourrait être un bon choix (et il est bien supporté par Express).

// EDIT

Selon la documentation de Connect il vous suffit de mettre en œuvre get , set y destroy méthodes. Le code suivant devrait fonctionner :

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

Il suffit de faire appel à MongoDb (ou à toute autre base de données, même si je recommande d'utiliser une base de données non permanente comme Redis) pour stocker les données de session. Lisez également le code source d'autres implémentations pour vous faire une idée.

2voto

user1409983 Points 11

C'est probablement évident pour les utilisateurs expérimentés de nœuds mais cela m'a surpris :

Vous devez configurer la session du nœud - par exemple

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

avant initialisation de la session du passeport - par ex.

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

Si vous appelez passport.session() en premier, cela ne fonctionnera pas (et il ne vous préviendra pas). Je pensais que le problème venait des fonctions utilisateur serialize/deserialize et j'ai perdu des heures.

1voto

arg20 Points 1020

J'utilise mongoose, j'ai essayé le code présenté dans les réponses ci-dessus et cela n'a pas fonctionné pour moi. J'ai obtenu cette erreur quand je l'ai fait :

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

Cependant, cela fonctionne pour moi :

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

Note : Si vous n'avez pas MongoStore pour une raison quelconque, vous devez le faire :

npm install connect-mongo --save

alors :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X