Passport.js - Fehler: Benutzer konnte nicht in die Sitzung serialisiert werden

179

Ich habe ein Problem mit dem Passport.js-Modul und Express.js.

Dies ist mein Code und ich möchte nur einen fest codierten Login für den ersten Versuch verwenden.

Ich bekomme immer die Nachricht:

Ich habe viel gesucht und einige Beiträge im Stackoverflow gefunden, aber ich habe den Fehler nicht bekommen.

Error: failed to serialize user into session
    at pass (c:\Development\private\aortmann\bootstrap_blog\node_modules\passport\lib\passport\index.js:275:19)

Mein Code sieht so aus.

'use strict';

var express = require('express');
var path = require('path');
var fs = require('fs');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var nodemailer = require('nodemailer');

var app = express();

module.exports = function setupBlog(mailTransport, database){
var config = JSON.parse(fs.readFileSync('./blog.config'));

app.set('view options', {layout: false});

app.use(express.static(path.join(__dirname, '../', 'resources', 'html')));


app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({ secret: 'secret' }));
app.use(passport.initialize());
app.use(passport.session());


app.get('/blog/:blogTitle', function(req, res) {
  var blogTitle = req.params.blogTitle;
  if(blogTitle === 'newest'){
    database.getLatestBlogPost(function(post) {
      res.send(post);
    });
  } else {
    database.getBlogPostByTitle(blogTitle, function(blogPost) {
      res.send(blogPost);
    });
  }
});

passport.use(new LocalStrategy(function(username, password, done) {
  // database.login(username, password, done);
  if (username === 'admin' && password === 'admin') {
    console.log('in');
    done(null, { username: username });
  } else {
    done(null, false);
  }
}));

app.post('/login', passport.authenticate('local', {
  successRedirect: '/accessed',
  failureRedirect: '/access'
}));





app.listen(8080);
console.log('Blog is running on port 8080');

}();

Vielen Dank.

user2244925
quelle

Antworten:

360

Es sieht aus wie Sie nicht implementieren passport.serializeUserund passport.deserializeUser. Versuchen Sie Folgendes hinzuzufügen:

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

passport.deserializeUser(function(user, done) {
  done(null, user);
});
Robertklep
quelle
2
Hat für mich gearbeitet. Warum muss ich den 'id'-Teil nicht so verwenden, wie er überall sonst geschrieben steht?
Schlenger
9
@schlenger es würde davon abhängen, wie Sie die Serialisierung implementieren. Manchmal serialisieren Sie nach Benutzer-ID, was bedeutet, dass die serializeUserFunktion nur die Benutzer-ID in der Sitzung speichert und deserializeUserdiese ID verwendet, um beispielsweise die Benutzerdaten aus einer Datenbank abzurufen. Dies soll verhindern, dass der Sitzungsspeicher die tatsächlichen Benutzerdaten selbst enthält.
Robertklep
+1 @robertklep Kommentar. Ich würde es immer vermeiden, Benutzerinformationen zu serialisieren, sondern nur IDs (aus Gründen der Aufblähung / Leistung persönlich).
Electblake
2
@robertklep Ich möchte es nicht in einer Sitzung speichern. Ich benutze JWT. Ist serializeUser / deserializeUser erforderlich? Ich möchte keine Sitzung. Ich benutze JWT
Internial
@Internial nicht sicher, ob Sie sie brauchen, aber es wäre eine einfache Sache zu testen.
Robertklep
44

Wenn Sie keine Sitzungen verwenden möchten, können Sie die Sitzung auf false setzen

app.post('/login', passport.authenticate('local', {
  successRedirect: '/accessed',
  failureRedirect: '/access',
  session: false
}));
Kevin
quelle
Aber das wird die Sitzung auf allen anderen Endpunkten nicht ausschalten (wo ich auch keine Sitzung möchte)
Jayarjo
17

Klingt so, als hätten Sie einen Teil des Passportjs-Setups verpasst, insbesondere diese beiden Methoden:

passport.serializeUser(function(user, done) {
    done(null, user._id);
    // if you use Model.id as your idAttribute maybe you'd want
    // done(null, user.id);
});

passport.deserializeUser(function(id, done) {
  User.findById(id, function(err, user) {
    done(err, user);
  });
});

Ich habe das bisschen über ._idvs. hinzugefügt, .idaber dieses Snippet stammt aus dem Abschnitt "Konfigurieren" der Dokumente. Lesen Sie es noch einmal und viel Glück :)

Electblake
quelle
2

Hier eine funktionierende, aber immer noch faule Art, Sitzungen zu verwenden und die Werte immer noch zu "serialisieren".

var user_cache = {};

passport.serializeUser(function(user, next) {
  let id = user._id;
  user_cache[id] = user;
  next(null, id);
});

passport.deserializeUser(function(id, next) {
  next(null, user_cache[id]);
});

Für den Fall oder seltsame Fehler fragen Sie sich einfach: "Setze ich '_id' in meinem Benutzerobjekt?" - In den meisten Fällen nicht. Verwenden Sie also ein geeignetes Attribut als Schlüssel.

Ganku Caelestis
quelle
0

Verwenden von Promise mit serializeUser & deserializeUser:

passport.serializeUser((user, done) => {
  done(null, user.id);
});

passport.deserializeUser((id, done) => {
  // console.log(`id: ${id}`);
  User.findById(id)
    .then((user) => {
      done(null, user);
    })
    .catch((error) => {
      console.log(`Error: ${error}`);
    });
});

In meinem Github-Repo finden Sie ein vollständiges Codebeispiel zur Lösung dieses Problems.

Isak La Fleur
quelle
-1

in passport.use ('local-login' ...) / oder / ('local-singup' ...)

Wenn err, müssen Sie "false" zurückgeben. err {return done (null, req.flash ('megsign', 'Benutzername existiert bereits #! #'));} true {return done (null, false, req.flash (') megsign ',' Benutzername existiert bereits #! # '));}

annguyen
quelle