web-dev-qa-db-de.com

PassportJS deserializeUser hat nie aufgerufen

Ich habe ein Passport-Setup eingerichtet, um Benutzer zu authentifizieren, die in Mongodb gespeichert sind. Scheint gut zu funktionieren: Die Authentifizierung ist erfolgreich/fehlgeschlagen und die Sitzungsvariablen werden gesetzt. Es kann jedoch nicht passieren, dass Passport nach einer Sitzung sucht. Etwas scheint ziemlich falsch zu sein, da die console.log-Anweisungen, die ich zum Callback deserializeUser hinzugefügt habe, niemals das Tageslicht sehen. Ich gehe davon aus, dass mein Problem damit zusammenhängt, dass deserializeUser niemals aufgerufen wird. Kann jemand meinen Fehltritt diagnostizieren?

// Passport configuration
passport.serializeUser(function(user, cb){ cb(null, user.id) });
passport.deserializeUser(function(uid, cb){
  console.log("Trying to deserialize user: "+uid);
  User.findById(uid, function(err, user){
    cb(err, user);
  });
});
// auth strategy function
passport.use(new LocalStrategy({usernameField: 'email'},
  function(email, pass, done){
    User.findOne({email: email}, function (err, user) {
      if (err)
        return done(err);
      if (!user)
        return done(null, false, {message: "Couldn't find user"});
      var crypted = bcrypt.hashSync(pass, user.salt);
      if(user.hashpass != crypted)
        return done(null, false, {message: "Bad password"});
      return done(null, user);
    });
  }
));

passport.CreateSession =  function (req, res, next) {
  passport.authenticate('local', function(err, user, info){
    if(err || !user)
      return res.json({status: "Failure: "+err});
    req.logIn(user, function (err){
      if(err)
        return res.json({status: "Failure: "+err});
      return res.json({status: "Authenticated"});
    });
  })(req, res, next);
};

mit folgenden Angaben in app.js:

app.post('/session', passport.CreateSession); // restify better
app.del('/session', passport.DestroySession);
app.get('/images', passport.CheckSession, routes.images);
33
Alex Westholm

Für alle anderen, die dieses Problem haben, sehen Sie sich Folgendes an:

app.use(session({ 
    secret: 'something', 
    cookie: { 
        secure: true
    }}));

Wenn Sie cookie.secure auf true gesetzt haben und KEIN SSL verwenden (d. H. Das https-Protokoll), wird der Cookie mit der Sitzungs-ID nicht an den Browser zurückgegeben, und alles schlägt fehl. Das Entfernen dieser Flagge löste das Problem für mich - es dauerte Stunden, um dies zu realisieren!

30
Dave Kerr

Wenn Sie den authenticate-Rückruf bei der Authentifizierung mit Passport verwenden, müssen Sie den Benutzer manuell anmelden. Es wird nicht für Sie angerufen.

passport.authenticate('local', function (err, user) {
    req.logIn(user, function (err) { // <-- Log user in
       return res.redirect('/'); 
    });
})(req, res);
23
Rick

Haben Sie use() 'd passport.session() Middleware? Wie in diesem Beispiel:

https://github.com/jaredhanson/passport-local/blob/v1.0.0/examples/login/app.js#L91

Das stellt die Sitzung wieder her und ruft deserializeUser auf, so dass es sich anhört, als ob das vielleicht fehlt.

11
Jared Hanson

Okay, ich habe fast 3 Tage gebraucht, um das Problem zu lösen, was zumindest in meinem Fall eine einfache Lösung ist. Ich musste app.use(require('cookie-parser')); und app.use(require('express-session')({ secret: 'keyboard cat', resave: false, saveUninitialized: false })); vor dem Aufruf von platzieren:

app.use(passport.initialize()); app.use(passport.session());

Hinweis: Diese Ausschnitte sind nicht mein eigentlicher Code. Ich habe ihn aus folgender Datei entnommen: https://github.com/passport/express-4.x-local-example > server.js -Datei; aber das ist der Kern davon.

1
Sharukh Mastan

Ich habe den ganzen Tag gegen dasselbe Problem gekämpft. Ich hatte einen benutzerdefinierten Rückruf für Autorisierungen eingerichtet (wie am Ende von http://passportjs.org/guide/authenticate/ ). Es sieht so aus, als ob Passport alle Anforderungsobjekte vorverarbeitet, noch bevor sie die andere Middleware erreichen (basierend auf einigen Protokollierungsanweisungen, die ich geschrieben habe). Als Teil dieser Vorverarbeitung werden die deserialisierten Benutzerinformationen in das Objekt request.user eingefügt. Leider scheint das Standardverhalten von passport.authenticate ('local', callback) Sitzungs- oder Cookie-Daten zu ignorieren und stattdessen davon auszugehen, dass der Benutzername und der PW im Anforderungsobjekt gesendet werden. Um das Problem zu beheben, musste ich zunächst das request.user -Objekt überprüfen. Wenn es existiert, bedeutet dies, dass Passport seine Vorverarbeitung durchgeführt hat, und ich konnte dann direkt login aufrufen. Hier ist meine Berechtigungsfunktion, die ich anstelle von passport.authenticate ('local') verwende:

function doAuth(request, response, next)
{ 

if (request.user) {
    request.logIn(request.user, function (err) {
        if (err) {
            console.log(err);
            response.status(500).json({message:
                    "Login failed. Auth worked. Nonsense"});
            return;
        }
        console.log("doAuth: Everything worked.");
        next();
    });
    return;
}

passport.authenticate('local', function(err, user, info) {
    if (err) {
        response.status(500).json({message: "Boo Passport!"});
        return; //go no further
        //until I figure out what errors can get thrown
    }
    if (user === false) {
        console.log("Authentication failed. Here is my error:");
        console.log(err);
        console.log("Here is my info:");
        console.log(info);
        response.status(500).json({message: "Authentication failed."});
        return;
    }
    request.logIn(user, function(err) {
        if (err) {
        console.log("Login failed. This is the error message:");
        console.log(err);
        response.status(500).json({message:"Login failed."});
            return;
        }
        console.log("doAuth: Everything worked. I don't believe it.");

        next();
    });
})(request, response, next);

 }
1
user3522492

in meinem Fall habe ich platziert

app.use(cookieSession({
  maxAge : 60*60*1000,
  keys : [key.cookieSession.key1]
}));

über

app.use(passport.initialize());
app.use(passport.session());

und es hat funktioniert.

0
Prakash Ujjwal

Heute stand ich vor demselben Problem, und in meinem Fall lag es daran, wie der Client die API-Aufrufe durchführt. Und der folgende Ansatz half mir, das Problem zu überwinden:

const doFetch(url, method = 'GET', body) {
  const headers = new Headers();
  headers.append('Content-Type', 'application/json');
  headers.append('Accept', 'application/json');
  headers.append('Cache', 'no-cache');
  const params = { 
    method, headers, 
    credentials: 'include' // The cookie must be sent!
  }
  if(body) {
    params.body = body;
  }
  return fetch(url, params);
}

Danach wurde deserializeUser richtig aufgerufen.

0
dhilt

In meinem Fall war es, weil ich diesen Code hatte:

app.get("/auth/google/callback", 
    passport.authenticate("google", { 
        failureRedirect: "/admin/login/?error",
    }),
    (req, res) => {
        return res.redirect("/admin/");
    },
);

Anscheinend wird in diesem Fall req.login () nicht aufgerufen (die Aufrufe deserialisieren). Ich habe es geändert und es hat funktioniert:

app.get("/auth/google/callback", 
    passport.authenticate("google", { 
        successRedirect: "/admin/", 
        failureRedirect: "/admin/login/?error",
    })
);
0
Lacho Tomov