Ich verwende passport.js, um die Authentifizierung in meiner Anwendung nodejs + express.js zu verarbeiten. Ich habe eine LocalStrategy eingerichtet, um Benutzer von Mongodb zu übernehmen
Mein Problem ist, dass Benutzer sich erneut authentifizieren müssen, wenn ich meinen Knotenserver neu starte . Dies ist ein Problem, da ich es aktiv entwickle und mich nicht bei jedem Neustart anmelden möchte ... (+ Ich verwende Node Supervisor)
Hier ist mein 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);
});
Und Setup der Sitzungsserialisierung:
passport.serializeUser(function(user, done) {
done(null, user.email);
});
passport.deserializeUser(function(email, done) {
User.findOne({email:email}, function(err, user) {
done(err, user);
});
});
Ich habe die in einem Blog angegebene Lösung (den Link wurde entfernt, da er nicht mehr existiert) mit connect-mongodb ohne Erfolg ausprobiert
app.use(express.session({
secret:'something else',
cookie: {maxAge: 60000 * 60 * 24 * 30}, // 30 days
store: MongoDBStore({
db: mongoose.connection.db
})
}));
EDIT zusätzliches Problem: Es sollte nur eine Verbindung hergestellt werden (Nutzung eines verbindungsbeschränkten mongohq-freien Dienstes)
EDIT 2- Lösung (als Edition ist mein Ruf zu niedrig, um meine Frage jetzt zu beantworten
Hier ist die Lösung, die ich endlich gefunden habe, indem ich eine von Mungos initiierte Verbindung verwendet habe
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');
})
}));
Antworten:
Es gibt eine OpenSource namens connect-mongo , die genau das tut, was Sie brauchen - die Sitzungsdaten in mongodb bleiben erhalten
Anwendungsbeispiel (mit Wiederverwendung einer
mongoose
geöffneten Verbindung):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} ) }));
Weitere Informationen finden Sie hier: https://github.com/kcbanner/connect-mongo
quelle
{db:mongoose.connection.db}
nicht funktioniert . Sie können verwenden,{mongooseConnection:mongoose.connection}
was tatsächlich funktioniertIch benutze Connect-Mongo wie folgt:
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());
quelle
Dies liegt daran, dass Sie MemoryStore (Standard) für Sitzungen verwenden. Sehen Sie sich diesen Code aus memory.js (Teil des Connect-Frameworks) an:
var MemoryStore = module.exports = function MemoryStore() { this.sessions = {}; };
und dieses Snippet aus session.js (Express)
function session(options){ /* some code */ , store = options.store || new MemoryStore /* some code */ }
Jetzt sollten Sie verstehen, dass jeder Serverneustart den MemoryStore zurücksetzt. Um die Daten zu behalten, müssen Sie einen anderen Sitzungsspeicher verwenden. Sie können sogar Ihre eigenen schreiben (sollte nicht zu schwierig sein), obwohl Redis (siehe diese Bibliothek ) eine gute Wahl sein könnte (und von Express gut unterstützt wird).
// BEARBEITEN
Nach der Connect - Dokumentation ist es genug für Sie , wenn Sie implementieren
get
,set
unddestroy
Methoden. Der folgende Code sollte funktionieren: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 }));
Sie müssen nur das Aufrufen von MongoDb (oder einer anderen Datenbank, obwohl ich weiterhin die Verwendung von Nichtpermament-Datenbanken wie Redis empfehle) zum Speichern von Sitzungsdaten implementieren. Lesen Sie auch den Quellcode anderer Implementierungen, um die Idee zu verstehen.
quelle
Dies ist wahrscheinlich für erfahrene Knotenbenutzer offensichtlich, hat mich aber überrascht:
Sie müssen die Knotensitzung konfigurieren - z
app.use(session({secret: "this_is_secret", store: ...}));
vor dem Initialisieren der Pass-Sitzung - z
Wenn Sie zuerst passport.session () aufrufen, funktioniert dies nicht (und Sie werden nicht gewarnt). Ich dachte, das Problem liege in der Serialisierung / Deserialisierung der Benutzerfunktionen und der verschwendeten Stunden.
quelle
Ich benutze Mungo, habe den in den obigen Antworten angegebenen Code ausprobiert und er hat bei mir nicht funktioniert. Ich habe diesen Fehler bekommen, als ich tat:
Error: db object already connecting, open cannot be called multiple times
Dies funktioniert jedoch für mich:
app.use(express.session({ secret:'secret', maxAge: new Date(Date.now() + 3600000), store: new MongoStore({mongoose_connection:mongoose.connection}) }))
Hinweis: Wenn Sie MongoStore aus irgendeinem Grund nicht haben, müssen Sie Folgendes tun:
dann:
var MongoStore = require('connect-mongo')(express)
quelle
Was ich letztendlich gemacht habe:
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 }) }));
Funktioniert bei mir.
quelle
Sie müssen den Speicher ändern, den Sie für Ihre Sitzungen verwenden. Der Standardspeicher 'MemoryStore' speichert die Sitzung nicht weiter, wenn Ihre Anwendung beendet wird. Schauen Sie sich die Express-Session auf Github an, um mehr darüber zu erfahren, welche anderen Geschäfte es gibt, wie die Mongo. (Kann mich nicht an den Namen erinnern)
quelle