Ich kann mein System nicht mit PassportJS abmelden. Es scheint, dass die Abmelde-Route aufgerufen wird, die Sitzung jedoch nicht entfernt wird. Ich möchte 401 zurückgeben, wenn der Benutzer nicht in einer bestimmten Route angemeldet ist. Ich rufe authenticateUser an, um zu prüfen, ob der Benutzer angemeldet ist.
Danke vielmals!
/******* This in index.js *********/
// setup passport for username & passport authentication
adminToolsSetup.setup(passport);
// admin tool login/logout logic
app.post("/adminTool/login",
passport.authenticate('local', {
successRedirect: '/adminTool/index.html',
failureRedirect: '/',
failureFlash: false })
);
app.get('/adminTool/logout', adminToolsSetup.authenticateUser, function(req, res){
console.log("logging out");
console.log(res.user);
req.logout();
res.redirect('/');
});
// ******* This is in adminToolSetup ********
// Setting up user authentication to be using user name and passport as authentication method,
// this function will fetch the user information from the user name, and compare the password for authentication
exports.setup = function(passport) {
setupLocalStrategy(passport);
setupSerialization(passport);
}
function setupLocalStrategy(passport) {
passport.use(new LocalStrategy(
function(username, password, done) {
console.log('validating user login');
dao.retrieveAdminbyName(username, function(err, user) {
if (err) { return done(err); }
if (!user) {
return done(null, false, { message: 'Incorrect username.' });
}
// has password then compare password
var hashedPassword = crypto.createHash('md5').update(password).digest("hex");
if (user.adminPassword != hashedPassword) {
console.log('incorrect password');
return done(null, false, { message: 'Incorrect password.' });
}
console.log('user validated');
return done(null, user);
});
}
));
}
function setupSerialization(passport) {
// serialization
passport.serializeUser(function(user, done) {
console.log("serialize user");
done(null, user.adminId);
});
// de-serialization
passport.deserializeUser(function(id, done) {
dao.retrieveUserById(id, function(err, user) {
console.log("de-serialize user");
done(err, user);
});
});
}
// authenticating the user as needed
exports.authenticateUser = function(req, res, next) {
console.log(req.user);
if (!req.user) {
return res.send("401 unauthorized", 401);
}
next();
}
Brices Antwort ist großartig , aber ich habe immer noch einen wichtigen Unterschied bemerkt, den ich machen muss. Die Passport-Anleitung schlägt vor, .logout()
(auch als .logOut()
aliasiert) zu verwenden:
app.get('/logout', function(req, res){
req.logout();
res.redirect('/'); //Can fire before session is destroyed?
});
Wie oben erwähnt, ist dies jedoch unzuverlässig. Ich fand es wie erwartet, als er den Vorschlag von Brice wie folgt umsetzte:
app.get('/logout', function (req, res){
req.session.destroy(function (err) {
res.redirect('/'); //Inside a callback… bulletproof!
});
});
Hoffe das hilft!
Lief in die gleiche Ausgabe. Die Verwendung von req.session.destroy();
anstelle von req.logout();
funktioniert, aber ich weiß nicht, ob dies die beste Vorgehensweise ist.
session.destroy
reicht möglicherweise nicht aus, um sicherzustellen, dass der Benutzer vollständig abgemeldet ist, müssen Sie auch das Sitzungscookie löschen.
Das Problem hierbei ist, dass, wenn Ihre Anwendung auch als API für eine Einzelseiten-App verwendet wird (nicht empfohlen, aber recht häufig), möglicherweise einige Anforderungen von Express verarbeitet werden, die vor der Abmeldung und nach der Abmeldung gestartet wurden. Wenn dies der Fall war, stellt diese länger laufende Anforderung die Sitzung nach dem Löschen wieder her. Und da der Browser beim nächsten Öffnen der Seite immer noch den gleichen Cookie enthält, werden Sie erfolgreich angemeldet.
req.session.destroy(function() {
res.clearCookie('connect.sid');
res.redirect('/');
});
Das ist was sonst vielleicht passiert:
Im Idealfall müssen Sie die Tokenauthentifizierung für API-Aufrufe verwenden und nur Sitzungen in einer Web-App verwenden, die nur Seiten laden. Selbst wenn Ihre Web-App nur zum Erhalt von API-Tokens verwendet wird, ist diese Race-Bedingung immer noch möglich.
Ich hatte das gleiche Problem, und es stellte sich heraus, dass es überhaupt kein Problem mit Passport-Funktionen war, sondern eher in der Art und Weise, wie ich meine /logout
-Route aufrief. Ich habe die Route mit Fetch aufgerufen:
(Schlecht)
fetch('/auth/logout')
.then([other stuff]);
Es stellt sich heraus, dass dabei keine Cookies gesendet werden, also wird die Sitzung nicht fortgesetzt und ich denke, die res.logout()
wird auf eine andere Sitzung angewendet. Auf jeden Fall können Sie Folgendes tun, indem Sie Folgendes tun:
(Gut)
fetch('/auth/logout', { credentials: 'same-Origin' })
.then([other stuff]);
Ich hatte die gleichen Probleme, Kapital O hat es behoben;
app.get('/logout', function (req, res){
req.logOut() // <-- not req.logout();
res.redirect('/')
});
Ich hatte kürzlich das gleiche Problem und keine der Antworten hat das Problem für mich behoben. Könnte falsch sein, aber es scheint mit der Rasse zu tun zu haben.
Das Ändern der Sitzungsdetails in die folgenden Optionen scheint das Problem für mich behoben zu haben. Ich habe es jetzt ungefähr 10 Mal getestet und alles scheint richtig zu funktionieren.
app.use(session({
secret: 'secret',
saveUninitialized: false,
resave: false
}));
Grundsätzlich habe ich gerade saveUninitialized
und resave
von true
in false
geändert. Das scheint das Problem behoben zu haben.
Nur als Referenz verwende ich die Standardmethode req.logout();
in meinem Abmeldepfad. Ich benutze die Session-Zerstörung nicht wie andere Leute erwähnt haben.
app.get('/logout', function(req, res) {
req.logout();
res.redirect('/');
});
Ich habe sowohl req.logout()
als auch req.session.destroy()
verwendet und funktioniert einwandfrei.
server.get('/logout', (req, res) => {
req.logout();
req.session.destroy();
res.redirect('/');
});
Um nur zu erwähnen, benutze ich Redis als Session Store.
Die Sitzung selbst zu zerstören, sieht seltsam aus ..
"express": "^4.12.3",
"passport": "^0.2.1",
"passport-local": "^1.0.0",
Ich sollte sagen, dass diese Konfiguration funktioniert gut. Der Grund für mein Problem war in der benutzerdefinierten sessionStore
, die ich hier definiert habe:
app.use(expressSession({
...
store: dbSessionStore,
...
}));
Um sicher zu sein, dass Ihr Problem auch hier kommentiert, speichern Sie die Zeile und führen Sie sie aus, ohne dass die Sitzung bestehen bleibt. Wenn dies funktioniert, sollten Sie in Ihren benutzerdefinierten Sitzungsspeicher wechseln. In meinem Fall wurde die set
-Methode falsch definiert. Wenn Sie die req.logout()
-Sitzungsablage verwenden, wird die destroy()
-Methode nicht aufgerufen, wie ich vorher gedacht habe. Stattdessen set
-Methode mit aktualisierter Sitzung aufgerufen.
Viel Glück, ich hoffe, diese Antwort wird Ihnen helfen.
Ich habe die Erfahrung gemacht, dass es manchmal nicht funktioniert, weil Sie den Pass nicht richtig einrichten können Zum Beispiel mache ich vhost
, aber bei der Hauptanwendung stelle ich einen Pass ein, der falsch ist.
app.js (warum falsch? bitte sehen Sie blockqoute weiter unten)
require('./modules/middleware.bodyparser')(app);
require('./modules/middleware.passport')(app);
require('./modules/middleware.session')(app);
require('./modules/app.config.default.js')(app, express);
// default router across domain
app.use('/login', require('./controllers/loginController'));
app.get('/logout', function (req, res) {
req.logout();
res.redirect('/');
});
// vhost setup
app.use(vhost('sub1.somehost.dev', require('./app.Host.sub1.js')));
app.use(vhost('somehost.dev', require('./app.Host.main.js')));
eigentlich muss es nicht möglich sein, sich anzumelden, aber ich schaffe das, weil ich weiterhin Fehler mache. indem Sie hier ein anderes Pass-Setup eingeben, so dass das Sitzungsformular app.js
für app.Host.sub1.js
verfügbar ist.
app.Host1.js
// default app configuration
require('./modules/middleware.passport')(app);
require('./modules/app.config.default.js')(app, express);
Wenn ich mich also abmelden möchte, funktioniert es nicht, weil app.js
etwas falsch gemacht hat, indem Sie passport.js
vor express-session.js
initialisieren, was falsch ist !!.
Dieser Code kann jedoch die Probleme trotzdem lösen, wie andere bereits erwähnen.
app.js
app.get('/logout', function (req, res) {
req.logout();
req.session.destroy(function (err) {
if (err) {
return next(err);
}
// destroy session data
req.session = null;
// redirect to homepage
res.redirect('/');
});
});
Aber in meinem Fall ist der richtige Weg ... tauschen Sie die express-session.js vor passport.js
Dokument auch erwähnen
Beachten Sie, dass die Aktivierung der Sitzungsunterstützung vollständig optional ist, obwohl es .__ ist. empfohlen für die meisten Anwendungen. Falls aktiviert, verwenden Sie unbedingt __. express.session () vor passport.session (), um sicherzustellen, dass das Login Sitzung wird in der richtigen Reihenfolge wiederhergestellt.
Also, Logout-Problem in meinem Fall gelöst durch ..
app.js
require('./modules/middleware.bodyparser')(app);
require('./modules/middleware.session')(app);
require('./modules/middleware.passport')(app);
require('./modules/app.config.default.js')(app, express);
// default router across domain
app.use('/login', require('./controllers/loginController'));
app.get('/logout', function (req, res) {
req.logout();
res.redirect('/');
});
app.Host1.js
// default app configuration
require('./modules/app.config.default.js')(app, express);
und jetzt funktioniert req.logout();
jetzt.
Ich hatte das gleiche Problem. Es stellte sich heraus, dass meine Passversion nicht mit Express 4.0 kompatibel war. Sie müssen nur eine ältere Version installieren.
npm install --save [email protected]
Das hat für mich funktioniert:
app.get('/user', restrictRoute, function (req, res) {
res.header('Cache-Control', 'no-cache, private, no-store, must-revalidate,
max-stale=0, post-check=0, pre-check=0');
});
Dadurch wird sichergestellt, dass Ihre Seite nicht im Cache gespeichert wird
Alle Beispiele hier führen eine Umleitung nach der req.session.destroy durch. Beachten Sie jedoch, dass Express sofort eine neue Sitzung für die Seite erstellt, zu der Sie weiterleiten. In Verbindung mit Postman fand ich das merkwürdige Verhalten, dass ein Passport-Login direkt nach der Abmeldung bewirkt, dass Passport erfolgreich ist, aber die Benutzer-ID nicht in der Sitzungsdatei speichern kann. Der Grund ist, dass Postman das Cookie in allen Anforderungen für diese Gruppe aktualisieren muss. Dies dauert eine Weile. Auch die Umleitung im Callback des Destroy hilft nicht.
Ich habe es gelöst, indem ich keine Weiterleitung ausführte, sondern nur eine Json-Nachricht zurücksende.
Anscheinend gibt es mehrere mögliche Ursachen für dieses Problem. In meinem Fall lag das Problem in der falschen Reihenfolge der Deklarationen, d. H. Der Endpunkt der Abmeldung wurde vor der Initialisierung des Passes deklariert. Die richtige Reihenfolge ist:
app.use(passport.initialize());
app.use(passport.session());
app.get('/logout', function(req, res) {
req.logout();
res.redirect('/');
});
Sie sollten req.logout () verwenden, um die Sitzung im Browser zu zerstören.
app.get('/logout', function(req, res) {
req.logout();
res.redirect('/'); // whatever the route to your default page is
});
Ich arbeite mit einem Programmierer, der vorschlägt, Benutzer von req zu entfernen:
app.get('/logout', function (req, res){
req.session.destroy(function (err) {
req.user = null;
res.redirect('/'); //Inside a callback… bulletproof!
});
});
Grund: Wir müssen aus req entfernen (Passwörter auch auf asynchrone Art und Weise), da nach der Abmeldung keine Benutzerdaten verwendet werden. __ und kann eine neue Sitzung erstellen und umleiten (aber noch nicht geschehen). Dies ist in unserer Verantwortung, irrelevante Dinge zu entfernen. PassportJS weist req.user nach dem Login Daten zu und entfernt sie auch, wenn wir req.logout () verwenden, aber es funktioniert manchmal nicht richtig als NodeJS Asynchronous
Ich hatte ein ähnliches Problem mit Passport 0.3.2.
Wenn ich Custom Callback für die Passport-Anmeldung und die Anmeldung verwende, blieb das Problem bestehen.
Das Problem wurde durch ein Upgrade auf Passport 0.4.0 und das Hinzufügen der Zeilen behoben
app.get('/logout', function(req, res) {
req.logOut();
res.redirect('/');
});
Keine der Antworten funktionierte für mich, daher werde ich meine weitergeben
app.use(session({
secret: 'some_secret',
resave: false,
saveUninitialized: false,
cookie: {maxAge: 1000} // this is the key
}))
und
router.get('/logout', (req, res, next) => {
req.logOut()
req.redirect('/')
})
Da Sie die Passport-Authentifizierung verwenden, bei der die eigene Sitzung über den connect.sid
-Cookie verwendet wird, besteht die einfachste Möglichkeit zum Abmelden darin, dass Passport die Sitzung behandelt.
app.get('/logout', function(req, res){
if (req.isAuthenticated()) {
req.logOut()
return res.redirect('/') // Handle valid logout
}
return res.status(401) // Handle unauthenticated response
})