web-dev-qa-db-de.com

Node + Express + Passport: Anforderungsbenutzer nicht definiert

Meine Frage ist ähnlich wie diese eine , aber es gab keine Einsicht in seine Lösung.

Ich benutze Passport, um mich mit Instagram zu authentifizieren. Nach erfolgreicher Authentifizierung werden Benutzer zu "/" weitergeleitet. Zu diesem Zeitpunkt hat die Anforderung das Benutzerobjekt (auch bekannt). Nach der Umleitung ist der req.user jedoch nicht definiert. : '(

Der ungerade Teil ist, dass passport.deserializeUser mit jeder Anfrage aufgerufen wird. Das Benutzerobjekt wird erfolgreich abgerufen, aber irgendwo in der Middleware-Straße wird der Benutzer req.user nicht festgelegt (oder wird 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
}
53
gojohnnygo

Haben Sie den Sitzungsstatus für Ihre App eingerichtet? Sie brauchen so etwas ...

app.use(session({ secret: 'anything' }));
app.use(passport.initialize());
app.use(passport.session());
34
Martin

Bei meinem Problem wurde nicht angegeben, dass Cookies gesendet werden sollen, wenn auf Client-Seite Fetch verwendet wird. Nach dem Einfügen der Anmeldeinformationen: 'include' Feld in der Anfrage hat es funktioniert.

fetch('/api/foo', {credentials: 'include'})
43
Jon Rodness

Ich bin bei Node super neu, aber es war ein Middleware-Problem für mich. BodyParser hinzugefügt und für die Korrektur neu angeordnet. 

Fehlerhafter 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

14
leylandjacob

Bisher habe ich diesen Code (funktionierte nicht):

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.

7
user3323765

Ja, aktivieren Sie Sitzungen wie @Martin. Wenn Sie jedoch die Version Express 4. * verwenden, werden Middleware-ähnliche Sitzungen nicht gebündelt. Sie müssen sie also einzeln installieren.

  1. Fügen Sie "express-session": "1.4.0" in Ihrem package.json hinzu
  2. npm installieren
  3. benutze es

;

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.

4
Adrian Enriquez

Ich habe das gleiche Problem, weil ich einfach folgenden Code aus der Express-Session-Dokumentation kopieren und einfügen habe, aber die Dokumentation nicht vollständig gelesen habe.

app.use(session({
  secret: 'keyboard cat',
  resave: false,
  saveUninitialized: true,
  cookie: { secure: true }
}))

In der Dokumentation wurde erwähnt:

Es ist jedoch eine https-fähige Website erforderlich, d. H. HTTPS ist notwendig für sichere Cookies. Wenn sicher eingestellt ist, und Sie auf Ihre .__ zugreifen. Site über HTTP wird der Cookie nicht gesetzt.

wenn Sie also nur eine HTTP-Verbindung haben, entfernen Sie die sichere Option und der folgende Code sollte funktionieren:

app.use(session({
  secret: 'keyboard cat',
  resave: false,
  saveUninitialized: true,
  //cookie: { secure: true } remove this line for HTTP connection
}))
4
ufxmeng

Versuchen Sie in den Routen Folgendes hinzuzufügen: {session: true}

app.get('/auto-login', passport.authenticate('cross', {session: true}))
3
Strawberry

Ich hatte genau dasselbe Problem mit Express 4 und nachdem ich so ziemlich alles ausprobiert hatte, was ich online finden konnte, habe ich es endlich geschafft, indem ich 'cookie-session' hinzufügte. 

var cookieSession = require('cookie-session');

app.use(cookieSession({
  keys: ['key1', 'key2']
}));
2
ergusto

Bei mir ging es um Kekse und Cors. Ich löste das Problem, indem ich meinem Server folgenden Code hinzufügte:

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();
}};
1
MmtBkn

Wenn Sie die http-Anfrage auf Clientseite verwenden, denken Sie daran, die Anmeldeinformationen beizufügen. In Angular2 müssen Sie das Optionsargument hinzufügen: {withCredentials: true}. Danach haben Sie die gleiche req.sessionID, bis Sie sie erneut zurücksetzen.

this._http.get("endpoint/something", { withCredentials: true })
1
Honzik

Sobald Sie Ihre Expresssitzung eingerichtet haben, stellen Sie sicher, dass Sie Passport serialisieren und deserialisieren. In der Funktion deserialize wird dann req.user generiert. Siehe Erklärung hier aus einer anderen Stackoverflow-Frage.

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


passport.deserializeUser(function(user, done) {
 done(null, user);
});
1
Aric Sangchat

Wenn Ihr Middleware-Stack unklar ist, vorausgesetzt, Sie haben Session-Middleware irgendwo - können Sie die Sitzung vor der Weiterleitung speichern:

if (req.user) {
    req.session.save(function (err) {
        if (err) {
            // ... panic!
        }
        res.redirect("/user/" + req.user._id);
    });
    return;
}
0
exclsr

Meine zwei Cents: 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
  }
})
);
0
Ruizhen Mai

Während Sie passport.authenticate ausführen, können Sie session: true hinzufügen, um Ihr Problem zu beheben:

app.post("/login", passport.authenticate('local', {
    'failureRedirect': '/login',
    'session': true
}), (req, res)=>{ res.redirect("/"); });
0
Mahesh

Der Server sendet den SetCookie-Header und dann das Browser-Handle, um ihn zu speichern. Anschließend wird der Cookie mit Anforderungen gesendet, die innerhalb eines Cookie-HTTP-Headers an denselben Server gesendet wurden.

Ich musste withCredentials setzen: true in meinem Client. (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 zu 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();
  }
});
0
Sunny Sultan

Wenn Sie einen Benutzer authentifizieren, wird der Anforderungswert req.user gefüllt. Um festzustellen, ob der Benutzer identifiziert und diesen Wert eingegeben wird, wird ein Cookie verwendet. Wenn Sie wie ich die Sitzung mit sicheren Cookies konfigurieren, sind Cookies nur über HTTPS verfügbar. Dies ist nicht die Standardkonfiguration für einen lokalen Entwicklungsserver. Damit Cookies über HTTP funktionieren, wird der Kommentar von cookie: { secure: true } und req.user-Wert ordnungsgemäß konfiguriert:

this.app.use(session({
    resave: true,
    saveUninitialized: true,
    secret: process.env.SESSION_SECRET || "a secret",
    // cookie: { secure: true },
}));

Wenn Sie vernünftigerweise nur HTTPS Cookies in der Produktion benötigen, können Sie Folgendes tun:

cookie: { secure: process.env.ENV === 'PRODUCTION' }
0
Alain1405

Meines unterschied sich von all dem. 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.

0
Breakpoint25

Ich hatte dasselbe Problem, sowohl mit req.isAuthenticated () als auch mit req.user. Ich habe das Problem gelöst

  • req.isAuthenticated () durch Ersetzen von findOne () durch find () in der findById () - Methode in deserialize () behoben, dann konnte ich authentifizierte req speichern, andernfalls wurde nichts zurückgegeben.

  • req.user durch Anpassen der Reihenfolge gelöst, zuerst sollte die Express-Sitzung gespeichert werden, dann sollte der Passport initialisiert werden, dann der nächste Sitzungsspeicher in passport.session () und danach können wir auf req.user zugreifen, nachdem die Session in passport.session gespeichert wurde ()

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 nach passport.session() auf req.user zugreifen, fügen Sie die Route unten hinzu.

0

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());
0
Marco Mantovani

Hatte genau das gleiche Problem. Für mich bestand die Lösung darin, "Client-Sessions" anstelle von "Express-Session" 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,
    }));
0
Luis