Ich habe Probleme, mein System dazu zu bringen, sich mit PassportJS abzumelden. Es scheint, dass die Abmelderoute aufgerufen wird, die Sitzung jedoch nicht entfernt wird. Ich möchte, dass 401 zurückgegeben wird, wenn der Benutzer nicht auf einer bestimmten Route angemeldet ist. Ich rufe authenticateUser an, um zu überprüfen, ob der Benutzer angemeldet ist.
Vielen Dank!
/******* 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();
}
javascript
node.js
express
logout
passport.js
Jeffrey Chen
quelle
quelle
req.logOut()
in Großbuchstaben auf, aber in Bezug auf die Anleitung sollte Ihr Code auch funktionieren.Antworten:
Brices Antwort ist großartig , aber ich bemerkte immer noch eine wichtige Unterscheidung; Der Passport-Leitfaden schlägt vor,
.logout()
Folgendes.logOut()
als solches zu verwenden (auch als Alias bezeichnet ):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 ich Brices Vorschlag wie folgt umsetzte:
app.get('/logout', function (req, res){ req.session.destroy(function (err) { res.redirect('/'); //Inside a callback… bulletproof! }); });
Hoffe das hilft!
quelle
client-sessions
? Die Zerstörungsfunktion benötigt kein Argument: github.com/mozilla/node-client-sessions/blob/master/lib/…[session-file-store] will retry, error on last attempt: Error: ENOENT: no such file or directory, open ...
Wie kann ich das beheben?Bin auf das gleiche Problem gestoßen. Verwenden
req.session.destroy();
stattreq.logout();
Arbeiten, aber ich weiß nicht, ob dies die beste Vorgehensweise ist.quelle
req.logout()
, aus Gründen der Vorwärtskompatibilität und so weiter, also habe ich nurreq.session.destroy();
nachher hinzugefügtreq.logout()
und das funktioniert gut.session.destroy
Möglicherweise reicht dies 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), einige Anforderungen von Express verarbeitet werden können, die vor dem Abmelden gestartet und nach dem Abmelden beendet wurden. Wenn dies der Fall wäre, würde diese länger laufende Anforderung die Sitzung in redis wiederherstellen, nachdem sie gelöscht wurde. Und da der Browser beim nächsten Öffnen der Seite immer noch dasselbe Cookie hat, werden Sie erfolgreich angemeldet.
req.session.destroy(function() { res.clearCookie('connect.sid'); res.redirect('/'); });
Das ist es, was vielleicht sonst passiert:
Idealerweise müssen Sie die Token-Authentifizierung für API-Aufrufe verwenden und nur Sitzungen in einer Web-App verwenden, die nur Seiten lädt. Selbst wenn Ihre Web-App nur zum Abrufen von API-Token verwendet wird, ist diese Race-Bedingung weiterhin möglich.
quelle
connect.sid
Abmelden entführt werden, sollte sich keine andere Partei wie Sie anmelden können, nachdem Sie sich abgemeldet haben.Ich hatte das gleiche Problem, und es stellte sich heraus, dass es überhaupt kein Problem mit Passport-Funktionen gab, sondern vielmehr mit der Art und Weise, wie ich meine
/logout
Route anrief . Ich habe fetch verwendet, um die Route aufzurufen:(Schlecht)
fetch('/auth/logout') .then([other stuff]);
Es stellt sich heraus, dass dadurch keine Cookies gesendet werden, sodass die Sitzung nicht fortgesetzt wird und ich denke, dass die Sitzung
res.logout()
auf eine andere Sitzung angewendet wird. Wenn Sie Folgendes tun, wird das Problem auf jeden Fall behoben:(Gut)
fetch('/auth/logout', { credentials: 'same-origin' }) .then([other stuff]);
quelle
Ich hatte die gleichen Probleme, Kapital O hat es behoben;
app.get('/logout', function (req, res){ req.logOut() // <-- not req.logout(); res.redirect('/') });
Bearbeiten: Dies ist kein Problem mehr.
quelle
logout
undlogOut
wurden im Jahr 2015 zueinander voreingenommen: github.com/jaredhanson/passport/blame/…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 einer Rennbedingung 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 mich gerade verändert
saveUninitialized
undresave
vontrue
bisfalse
. Das scheint das Problem behoben zu haben.Nur als Referenz verwende ich die Standardmethode
req.logout();
in meinem Abmeldepfad. Ich benutze die Sitzung nicht zerstören, wie andere Leute erwähnt haben.app.get('/logout', function(req, res) { req.logout(); res.redirect('/'); });
quelle
Ich habe beide verwendet
req.logout()
undreq.session.destroy()
und funktioniert gut.server.get('/logout', (req, res) => { req.logout(); req.session.destroy(); res.redirect('/'); });
Nur um zu erwähnen, ich benutze Redis als Session Store.
quelle
session.destroy
ist asynchron und erfordert einen Rückruf. Sie solltenres.redirect('/');
diesen Rückruf anrufen .Keine der Antworten hat für mich funktioniert, daher werde ich meine teilen
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('/') })
quelle
Die Sitzung selbst zu zerstören sieht komisch aus. Ich hatte dieses Problem mit der nächsten Konfiguration:
"express": "^4.12.3", "passport": "^0.2.1", "passport-local": "^1.0.0",
Ich sollte sagen, dass diese Konfiguration gut funktioniert . Der Grund für mein Problem war der Brauch
sessionStore
, den ich hier definiert habe:app.use(expressSession({ ... store: dbSessionStore, ... }));
Um sicherzugehen, dass auch hier Ihr Problem auftritt, kommentieren Sie einfach die Speicherzeile und führen Sie sie aus, ohne dass die Sitzung bestehen bleibt. Wenn es funktioniert, sollten Sie in Ihrem benutzerdefinierten Sitzungsspeicher stöbern. In meinem Fall wurde die
set
Methode falsch definiert. Wenn Sie diereq.logout()
Session Store-destroy()
Methode verwenden, wird diese nicht wie zuvor beschrieben aufgerufen. Stattdessen aufgerufeneset
Methode mit aktualisierter Sitzung.Viel Glück, ich hoffe diese Antwort wird Ihnen helfen.
quelle
Ich habe die Erfahrung gemacht, dass es manchmal nicht funktioniert, weil Sie den Pass nicht richtig einrichten können. Zum Beispiel,
vhost
aber in der Haupt-App richte ich einen Pass wie diesen ein, was falsch ist.app.js (warum falsch? siehe Blockqoute 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 mehr Fehler mache. indem Sie hier ein anderes Pass-Setup einfügen, damit das Sitzungsformular für
app.js
verfügbar istapp.host.sub1.js
app.host.sub1.js
// default app configuration require('./modules/middleware.passport')(app); require('./modules/app.config.default.js')(app, express);
Also, wenn ich mich abmelden möchte ... funktioniert es nicht, weil
app.js
etwas falsch gemacht wurde , indem ichpassport.js
vorherexpress-session.js
mit der Initialisierung begonnen habe , was falsch ist !!Dieser Code kann die Probleme jedoch trotzdem lösen, wie andere 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('/'); }); });
Dokument auch erwähnen
Also, Problem mit der Abmeldung in meinem Fall behoben 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.host.sub1.js
// default app configuration require('./modules/app.config.default.js')(app, express);
und jetzt
req.logout();
ist jetzt Arbeit.quelle
einfach req.logOut () hinzufügen; löste dieses Problem; "O" sollte groß geschrieben werden
quelle
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 express@3.0.0
quelle
Das hat bei mir 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'); });
Es stellt sicher, dass Ihre Seite nicht im Cache gespeichert wird
quelle
Ich arbeite mit einem Programmierer, der vorschlägt, den 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 (passportjs tun dies auch, aber asynchron), da nach dem Abmelden keine Benutzerdaten verwendet werden. Dies spart Speicherplatz und kann dazu führen, dass passportjs Benutzerdaten gefunden werden und möglicherweise eine neue Sitzung erstellen und umleiten (aber nicht) noch passieren) Übrigens liegt es in unserer Verantwortung, irrelevante Dinge zu entfernen. PassportJS weist req.user nach der Anmeldung Daten zu und entfernt sie auch, wenn wir req.logout () verwenden, aber es funktioniert möglicherweise manchmal nicht richtig als NodeJS Asynchronous
quelle
Ich hatte ein ähnliches Problem mit Passport 0.3.2.
Wenn ich Custom Callback für die Passport-Anmeldung und -Anmeldung verwende, bleibt das Problem bestehen.
Das Problem wurde durch ein Upgrade auf Passport 0.4.0 und Hinzufügen der Zeilen gelöst
app.get('/logout', function(req, res) { req.logOut(); res.redirect('/'); });
quelle
Anscheinend gibt es mehrere mögliche Ursachen für dieses Problem. In meinem Fall lag das Problem in der falschen Reihenfolge der Deklarationen, dh der Abmeldeendpunkt wurde vor der Passinitialisierung deklariert. Die richtige Reihenfolge ist:
app.use(passport.initialize()); app.use(passport.session()); app.get('/logout', function(req, res) { req.logout(); res.redirect('/'); });
quelle
Da Sie die Passauthentifizierung verwenden, bei der eine eigene Sitzung über das
connect.sid
Cookie verwendet wird, können Sie die Sitzung am einfachsten mit dem Abmelden abwickeln.app.get('/logout', function(req, res){ if (req.isAuthenticated()) { req.logOut() return res.redirect('/') // Handle valid logout } return res.status(401) // Handle unauthenticated response })
quelle
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 umleiten. In Kombination mit Postman habe ich das seltsame Verhalten festgestellt, dass eine Passport-Anmeldung direkt nach dem Abmelden den Effekt hat, dass Passport erfolgreich ist, die Benutzer-ID jedoch nicht in der Sitzungsdatei gespeichert werden kann. Der Grund dafür ist, dass Postman das Cookie in allen Anforderungen für diese Gruppe aktualisieren muss. Dies dauert eine Weile. Auch die Weiterleitung im Rückruf der Zerstörung hilft nicht.
Ich habe es gelöst, indem ich keine Weiterleitung durchgeführt habe, sondern nur eine JSON-Nachricht zurückgegeben habe.
quelle
Dies ist immer noch ein Problem.
Was ich getan habe, war,
req.session.destroy(function (err) {});
auf der Serverseite und auf der Clientseite zu verwenden, wann immer sie sich abmelden:const logout = () => { const url = '/users/logout' fetch(url) setTimeout(function () { location.reload(); }, 500);
Auf diese Weise ist der Benutzer beim Aktualisieren der Seite ohne Sitzung. Stellen Sie einfach sicher, dass Sie zur richtigen Seite umleiten, wenn niemand authentifiziert ist.
Vielleicht nicht der beste Ansatz, aber er funktioniert.
quelle
Sie können versuchen, die Sitzung manuell neu zu generieren:
app.get('/logout', (req, res) => { req.logOut(); req.session.regenerate(err => { err && console.log(err); }); res.redirect('/'); });
Dadurch werden keine anderen Daten (wie der Reisepass) aus der Sitzung entfernt.
quelle
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 });
quelle
Ich weiß nicht wie, habe aber
ng-href="https://stackoverflow.com/signout"
mein Problem gelöst. Früher habe ich den Dienst zum Abmelden verwendet, aber stattdessen habe ich ihn direkt verwendet.quelle
In meinem Fall hat die Verwendung eines Rückrufs, der an übergeben wurde,
req.session.destroy
nur teilweise geholfen, und ich musste auf diesen Hack zurückgreifen:req.session.destroy(); setTimeout(function() { res.redirect "/"; }, 2000);
Ich weiß nicht, warum dies die einzige Lösung ist, die ich zur Arbeit bringen konnte, aber leider hat die Antwort von @ JulianLloyd bei mir nicht konsequent funktioniert.
Dies hat möglicherweise etwas mit der Tatsache zu tun, dass meine Live-Anmeldeseite SSL verwendet (ich konnte das Problem nicht auf der Staging-Site oder auf meinem lokalen Host reproduzieren). Möglicherweise ist in meiner App noch etwas anderes los. Ich verwende das Derby-Passport-Modul, da meine App das Derby- Framework verwendet. Daher ist es schwierig, das Problem zu isolieren.
Es ist eindeutig ein Zeitproblem, da ich zuerst eine Zeitüberschreitung von 100 ms versucht habe, was nicht ausreichend war.
Leider habe ich noch keine bessere Lösung gefunden.
quelle