Meine Frage ist ähnlich wie diese ein , aber es gab keinen Einblick in seine Lösung.
Ich verwende Passport, um über Instagram zu authentifizieren. Nach erfolgreicher Authentifizierung werden Benutzer zu "/" weitergeleitet. Zu diesem Zeitpunkt hat die Anforderung das Benutzerobjekt (auch bekannt als es funktioniert). Sobald ich jedoch umleitung, ist der req.user undefiniert. : '(
Der seltsame Teil ist, dass passport.deserializeUser bei jeder Anforderung aufgerufen wird. Das Benutzerobjekt wird erfolgreich abgerufen, aber irgendwo auf der Middleware-Straße wird req.user nicht festgelegt (oder nicht festgelegt).
// on successful auth, goto "/"
app.get('/', function(req, res) {
// if the request has the user object, go to the user page
if (req.user) {
res.redirect("/user/" + req.user._id);
}
res.render("index");
}
app.get('/user/:uid', function(req, res) {
console.log(req.user) // undefined
}
node.js
express
passport.js
gojohnnygo
quelle
quelle
app.use(...)
Besonders Middleware ( ). Es kann sein, dass Ihre Sitzungscookies einen zu geringen Ablauf haben oder dass die Reihenfolge der Middleware falsch ist.Antworten:
Haben Sie den Sitzungsstatus für Ihre App eingerichtet? Du brauchst so etwas ...
app.use(session({ secret: 'anything' })); app.use(passport.initialize()); app.use(passport.session());
quelle
undefined
Nachricht.app.use(session({secret : 'anything'});
jetzt , dass Express-Sitzung sein eigenes Paket und nicht Teil der Expresspassport.session()
benötigt, wenn ich keine Sitzungen verwende?Mein Problem bestand nicht darin, Cookies zu senden, wenn Fetch auf der Clientseite verwendet wird. Es funktionierte, nachdem das Feld "Anmeldeinformationen" in die Anforderung aufgenommen wurde.
fetch('/api/foo', {credentials: 'include'})
quelle
withCredentials
Flag verwenden, um anzugeben, dass Cookies tatsächlich zurückgesendet werden sollen. Siehe developer.mozilla.org/en-US/docs/Web/API/Request/credentials . Beachten Sie auch, dass die Syntax anders ist, wenn Sie Axios anstelle der Abruf-API verwenden.Ich bin super neu bei Node, aber es war ein Middleware-Problem für mich. BodyParser hinzugefügt und neu angeordnet, um das Problem zu beheben.
Defekter Code:
app.use(express.cookieParser('secret')); app.use(express.cookieSession()); app.use(express.session({ secret: 'anything' })); app.use(passport.initialize()); app.use(passport.session()); app.use(app.router); app.use(express.static(path.join(__dirname, 'public')));
Arbeitscode:
app.use(express.static(path.join(__dirname, 'public'))); app.use(express.cookieParser()); app.use(express.bodyParser()); app.use(express.session({ secret: 'anything' })); app.use(passport.initialize()); app.use(passport.session()); app.use(app.router);
Hoffe das hilft
quelle
express.static
als einer der letzten Middleware war Brechen alles Auth für mich zusammen. es war nicht einmal konsequentes Verhalten, manchmal funktionierte es, manchmal nicht. Ich vermute, dass etwas im Express / Erwähnten Libs-Code sehr lückenhaft und anfällig für Rennbedingungen ist.Zuvor habe ich diesen Code (hat nicht funktioniert):
app.use(express.static(path.join(__dirname, 'public'))); app.use(cookieParser('abcdefg')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({extended: true})); app.use(session({ secret: 'abcdefg', resave: true, saveUninitialized: false, cookie: { secure: true } // this line })); app.use(passport.initialize()); app.use(passport.session()); app.use(require('stylus').middleware(path.join(__dirname, 'public')));
Dann entferne ich die Cookie-Option aus dem Sitzungsinitialisierer:
app.use(express.static(path.join(__dirname, 'public'))); app.use(cookieParser('abcdefg')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({extended: true})); app.use(session({ secret: 'abcdefg', resave: true, saveUninitialized: false })); app.use(passport.initialize()); app.use(passport.session()); app.use(require('stylus').middleware(path.join(__dirname, 'public')));
und jetzt funktioniert es.
quelle
Ich habe das gleiche Problem, weil ich nur den folgenden Code aus der Express-Sitzungsdokumentation kopiere und einfüge, aber die Dokumentation nicht vollständig lese.
app.use(session({ secret: 'keyboard cat', resave: false, saveUninitialized: true, cookie: { secure: true } }))
In der Dokumentation wurde Folgendes erwähnt:
Wenn Sie also nur eine HTTP-Verbindung haben, entfernen Sie die sichere Option. Der folgende Code sollte funktionieren:
app.use(session({ secret: 'keyboard cat', resave: false, saveUninitialized: true, //cookie: { secure: true } remove this line for HTTP connection }))
quelle
Ich hatte genau das gleiche Problem mit Express 4 und nachdem ich so ziemlich alles ausprobiert hatte, was ich online finden konnte, gelang es mir schließlich, es durch Hinzufügen einer "Cookie-Sitzung" zum Laufen zu bringen.
var cookieSession = require('cookie-session'); app.use(cookieSession({ keys: ['key1', 'key2'] }));
quelle
Ja, aktiviere Sitzungen, wie @Martin sagt. Wenn Sie jedoch die Express 4. * -Version verwenden, werden Middleware-ähnliche Sitzungen nicht gebündelt, sodass Sie sie einzeln installieren müssen.
;;
var express = require('express'); var cookieParser = require('cookie-parser') var session = require('express-session') var app = express() app.use(cookieParser()) // required before session. app.use(session({secret: 'keyboard cat'}))
Weitere Informationen finden Sie in der Express-Sitzungsdokumentation.
quelle
Versuchen Sie in Routen Folgendes hinzuzufügen:
{session: true}
app.get('/auto-login', passport.authenticate('cross', {session: true}))
quelle
req.user
wird nicht festgelegt, wenn Siesession: false
in den Optionen Ihres Anrufs angebenpassport.authenticate
.{ session: true }
scheint Standard zu sein.passport-twitter
und setze Sitzung explizit funktioniert nicht für mich. In der gleichen App,passport-google-auth
die genau die gleichen Codezeilen ausführt, ist in Ordnung.Wenn Sie einen Benutzer authentifizieren, wird der Anforderungswert
req.user
gefüllt. Um zu wissen, ob der Benutzer identifiziert und dieser Wert eingegeben wird, wird ein Cookie verwendet. Wenn Sie wie ich die Sitzung mit sicheren Cookies konfigurieren, sind Cookies nur über verfügbar. DiesHTTPS
ist nicht die Standardkonfiguration für beispielsweise einen lokalen Entwicklungsserver. Damit Cookies funktionierenHTTP
, werden Kommentarecookie: { secure: true }
undreq.user
Werte ordnungsgemäß konfiguriert:this.app.use(session({ resave: true, saveUninitialized: true, secret: process.env.SESSION_SECRET || "a secret", // cookie: { secure: true }, }));
Wenn Sie Cookies vernünftigerweise
HTTPS
nur in der Produktion verwenden möchten , können Sie Folgendes tun:cookie: { secure: process.env.ENV === 'PRODUCTION' }
quelle
Ich denke, jeder hat mehrere Fehler auf der Serverseite, die dieses Problem verursachen können.
Um diesen Fehler zu beheben, überprüfen Sie bitte diese Dinge:
Check 1 - Passport Serialization and Deserialization
Der richtige Weg, es zu tun (Mungo):
passport.serializeUser((user, done) => { done(null, user._id); }); passport.deserializeUser((_id, done) => { User.findById( _id, (err, user) => { if(err){ done(null, false, {error:err}); } else { done(null, user); } }); });
Überprüfen Sie 2 - Sitzungen
Überprüfen Sie, ob Ihr Cookie-Sitzungspaket ordnungsgemäß konfiguriert ist und funktioniert. Überprüfen Sie, ob auf der Clientseite tatsächlich Cookies angezeigt werden. Wenn Sie eine Express-Sitzung verwenden , stellen Sie bitte sicher, dass die Sitzungs-ID im Speicher oder im Cache (Redis) angezeigt wird.
Überprüfen Sie 3 - SSL Nginx
Stellen Sie sicher, dass Ihr Reverse-Proxy Cookies und den Anfragetyp unterstützt. Vergessen Sie nicht, die Cookie- / Sitzungskonfiguration zu überprüfen [
secure
Flag]Wenn ich auf diesen Fehler stoße, habe ich die
(user)
Rückruffunktion verwendet. Dann habe ich es mit korrigiert(err, user)
. Jetzt ist alles in Ordnung. Prost 🍻quelle
Bei mir ging es um Kekse und Cors. Ich habe das Problem gelöst, indem ich meinem Server folgenden Code hinzugefügt habe:
allowCrossDomain = function(req, res, next) { res.header('Access-Control-Allow-Origin', 'http://localhost:3000'); // your website res.header('Access-Control-Allow-Credentials', 'true'); res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS'); res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With'); if ('OPTIONS' === req.method) { res.send(200); } else { next(); }};
quelle
Sobald Sie Ihre Express-Sitzung eingerichtet haben, stellen Sie sicher, dass Sie Passport serialize & deserialize haben. In der Deserialize-Funktion wird dann req.user generiert. Siehe Erklärung hier von einer anderen Stackoverflow-Frage.
passport.serializeUser(function(user, done) { done(null, user); }); passport.deserializeUser(function(user, done) { done(null, user); });
quelle
Wenn Sie die http-Anforderung auf der Clientseite verwenden, denken Sie daran, Anmeldeinformationen anzuhängen. In Angular2 müssen Sie das Optionsargument {withCredentials: true} hinzufügen. Danach haben Sie dieselbe req.sessionID, bis Sie sie erneut zurücksetzen.
this._http.get("endpoint/something", { withCredentials: true })
quelle
Meins war anders als all diese. Ich hatte zuvor auf localhost eine Wordpress-Site entwickelt und dann zu einem separaten Node / React-Projekt gewechselt.
Das Cookie von der Wordpress-Site war noch vorhanden und wurde gesendet, da beide Projekte auf localhost ausgeführt wurden. Dies verursachte das Problem.
Ich musste die Cookies für localhost löschen und dann funktionierte es.
quelle
Wenn Ihre Middleware - Stack unklar ist, Sie Session - Middleware unter der Annahme haben irgendwo , können Sie die Sitzung vor der Umleitung speichern:
if (req.user) { req.session.save(function (err) { if (err) { // ... panic! } res.redirect("/user/" + req.user._id); }); return; }
quelle
Haben Sie versucht, Ihren secretKey in den CookieParser einzufügen?
var passport = require('passport'); var expressSession = require('express-session'); app.use(express.static(path.join(__dirname, 'public'))); app.use(cookieParser('mySecretKey')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); app.use(expressSession({ secret: 'mySecretKey', resave: false, saveUninitialized: true })); app.use(passport.initialize()); app.use(passport.session());
quelle
Hatte genau das gleiche Problem. Für mich bestand die Lösung darin, "Client-Sitzungen" anstelle von "Express-Sitzungen" zu verwenden. Wahrscheinlich schlechte Sitzungskonfiguration?
Nicht funktionierender Code:
var session = require('express-session'); app.use(bodyParser.urlencoded({ extended: false })); app.use(express.static(path.join(__dirname, 'public'))); app.use(cookieParser()); app.use(bodyParser.json()); app.use(session({ secret: 'random string', resave: true, saveUninitialized: true, cookie: { secure: true } }));
Arbeitscode:
var session = require('client-sessions'); app.use(bodyParser.urlencoded({ extended: false })); app.use(express.static(path.join(__dirname, 'public'))); app.use(cookieParser()); app.use(bodyParser.json()); app.use(session({ cookieName: 'session', secret: 'random string', duration: 30 * 60 * 1000, activeDuration: 5 * 60 * 1000, }));
quelle
Ich hatte das gleiche Problem, sowohl mit req.isAuthenticated () als auch mit req.user. Hier ist, wie ich es gelöst habe
req.isAuthenticated () wurde behoben, indem findOne () durch find () in der findById () -Methode in deserialize () ersetzt wurde. Dann konnte ich authentifizierte req speichern, andernfalls wurde nichts zurückgegeben.
req.user durch Anpassen der Reihenfolge aufgelöst, zuerst sollte die Express-Sitzung gespeichert werden, dann sollte der Pass initialisiert werden, dann der nächste Sitzungsspeicher in passport.session () und danach können wir auf req.user zugreifen, nachdem wir die Sitzung in passport.session () gespeichert haben.
app.use(session(...)); app.use(passport.initialize()); app.use(passport.session()); // Now we can access req.user so after we will call req.user, if we write it above these, it will always return underfined app.use(function(req, res, next){ res.locals.user = req.user || null next(); })
Wenn Sie danach auf req.user zugreifen
passport.session()
, fügen Sie unten Ihre Route hinzu.quelle
Währenddessen
passport.authenticate
können Sie hinzufügensession: true
, um Ihr Problem zu beheben:app.post("/login", passport.authenticate('local', { 'failureRedirect': '/login', 'session': true }), (req, res)=>{ res.redirect("/"); });
quelle
Meine zwei Cent: nicht funktionierender Code:
server.use( session({ secret: "secretsssss", rolling: false, resave: false, saveUninitialized: false, cookie: { sameSite: true, //this line maxAge: 60 * 60 * 1000 } }) );
Arbeitscode:
server.use( session({ secret: "secretsssss", rolling: false, resave: false, saveUninitialized: false, cookie: { sameSite: false, // i think this is default to false maxAge: 60 * 60 * 1000 } }) );
quelle
Der Server sendet den SetCookie-Header und dann das Browser-Handle, um ihn zu speichern. Anschließend wird das Cookie mit Anforderungen an denselben Server in einem Cookie-HTTP-Header gesendet.
Ich musste withCredentials: true in meinem Client festlegen. (axios.js)
const config = { withCredentials: true, headers: { 'Content-Type': 'application/json', }, }; axios.put(url, { page: '123' }, config) .then(res => console.log('axios', res)) .catch(err => console.log('axios', err));
Dann treten CORS-Probleme auf.
Also habe ich dies meinem Express-Server hinzugefügt:
app.use(function(req, res, next) { res.header('Access-Control-Allow-Credentials', true); res.header('Access-Control-Allow-Origin', req.headers.origin); res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE'); res.header('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept'); if ('OPTIONS' == req.method) { res.send(200); } else { next(); } });
quelle
Ich bin auf dasselbe Problem gestoßen, aber mein Problem hing eher mit einem Missverständnis des Unterschieds zwischen
passport.authorize
undpassport.authenticate
zu Beginn der OAuth-Flow- und OAuth-Rückrufrouten zusammen.passport.authorize
Diereq.user
Variable wird nicht beeinflusst , aber da ich nur den Beispielcode aus den Dokumenten der Strategie kopiert und eingefügt habe, habe ich nicht bemerkt, dass die falsche Methode verwendet wurde. Nach dem Wechsel zupassport.authenticate
Benutzervariable war verfügbar.Hoffe, dies hilft jedem, der unwissentlich das Gleiche tut.
quelle
Ändern Sie die Reihenfolge von diesem:
app.set("view engine", "ejs"); app.use(bodyParser.urlencoded({ extended: true }));
dazu:
app.use(bodyParser.urlencoded({ extended: true })); app.set("view engine", "ejs");
quelle
Ich habe den Cookie-Parser zusammen mit einer Express-Sitzung wie dieser verwendet:
var express = require("express"); // 4.16.1 var cors = require("cors"); // 2.8.5 var cookieParser = require("cookie-parser"); // 1.4.4 var expressSession = require("express-session"); // 1.17.1 var app = express(); app.use( cors({ origin: "http://localhost:3000", credentials: true, }) ); app.use(express.json()); app.use(express.urlencoded({ extended: true })); app.use( expressSession({ secret: "secret123", resave: true, saveUninitialized: true, cookie: { maxAge: 60 * 60 * 24 * 1000 }, }) ); app.use(cookieParser("secret123")); // this line
Das Setzen des Cookie-Parsers vor der Express-Sitzung hat bei mir folgendermaßen funktioniert:
var express = require("express"); // 4.16.1 var cors = require("cors"); // 2.8.5 var cookieParser = require("cookie-parser"); // 1.4.4 var expressSession = require("express-session"); // 1.17.1 var app = express(); app.use( cors({ origin: "http://localhost:3000", credentials: true, }) ); app.use(express.json()); app.use(express.urlencoded({ extended: true })); app.use(cookieParser("secret123")); app.use( expressSession({ secret: "secret123", resave: true, saveUninitialized: true, cookie: { maxAge: 60 * 60 * 24 * 1000 }, }) );
quelle
Ich hatte ein anderes Problem, etwas mit bcrpt-Node- und Pfeilfunktionen.
Code, der funktioniert:
userSchema.methods.generateHash = function (password) { return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null); }; userSchema.methods.isValidPassword = function (password) { return bcrypt.compareSync(password, this.password); };
Code, der nicht funktioniert:
userSchema.methods.generateHash = (password) => { return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null); }; userSchema.methods.isValidPassword = (password) => { return bcrypt.compareSync(password, this.password); };
quelle