Passport.js - Errore: impossibile serializzare l'utente nella sessione


180

Ho riscontrato un problema con il modulo Passport.js e Express.js.

Questo è il mio codice e voglio solo usare un login hardcoded per il primo tentativo.

Ricevo sempre il messaggio:

Ho cercato molto e ho trovato alcuni post in StackOverflow ma non ho riscontrato l'errore.

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

Il mio codice è simile a questo.

'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');

}();

Grazie.

Risposte:


363

Sembra che tu non abbia implementato passport.serializeUsere passport.deserializeUser. Prova ad aggiungere questo:

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

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

2
Ha funzionato per me. Perché non devo usare la parte 'id' come scritta altrove?
schlenger,

9
@schlenger dipende da come si implementa la serializzazione. A volte si serializza per ID utente, il che significa che la serializeUserfunzione memorizza solo l'id utente nella sessione e deserializeUserutilizza tale ID per recuperare i dati utente da un database (ad esempio). Questo per evitare che l'archiviazione della sessione contenga i dati dell'utente stesso.
robertklep,

+1 commento su @robertklep. Eviterei sempre di serializzare le informazioni dell'utente, ma solo gli ID (per motivi personali / perfetti).
electblake,

2
@robertklep Non voglio salvarlo in sessione. Sto usando JWT. SerializeUser / deserializeUser è richiesto? Voglio una sessione senza. Sto usando JWT
Intern

@Internial non sono sicuro se ne hai bisogno, ma sarebbe una cosa facile da testare.
robertklep,

44

Se si decide di non utilizzare le sessioni, è possibile impostare la sessione su false

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

Ma ciò non disattiverà la sessione su tutti gli altri endpoint (dove anche io non voglio alcuna sessione)
jayarjo

17

Sembra che tu abbia perso una parte dell'installazione di passportjs, in particolare questi due metodi:

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);
  });
});

Ho aggiunto un po 'su ._idvs. .idma questo frammento proviene dalla sezione Configura dei documenti, dacci un'altra lettura e buona fortuna :)


2

Qui un modo funzionante ma ancora pigro di usare le sessioni e ancora "serializzare" i valori.

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]);
});

in caso di errori strani o semplicemente chiediti: "Devo impostare '_id' nel mio oggetto utente?" - nella maggior parte dei casi no. Quindi usa un attributo appropriato come chiave.


0

Utilizzo di Promise con serializeUser e 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}`);
    });
});

Si prega di consultare il mio repository github per un esempio di codice completo su come risolvere questo problema.


-1

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

se err devi restituire "false" err {return done (null, req.flash ('megsign', 'Nome utente esiste già #! #'));} true {return done (null, false, req.flash (' megsign ',' Nome utente esiste già #! # '));}

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.