Passport.js - Error: no se pudo serializar al usuario en la sesión

179

Tengo un problema con el módulo Passport.js y Express.js.

Este es mi código y solo quiero usar un inicio de sesión codificado para el primer intento.

Siempre recibo el mensaje:

Busqué mucho y encontré algunas publicaciones en stackoverflow pero no obtuve el error.

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

Mi código se ve así.

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

}();

Gracias.

usuario2244925
fuente

Respuestas:

362

Parece que no implementaste passport.serializeUsery passport.deserializeUser. Intenta agregar esto:

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

passport.deserializeUser(function(user, done) {
  done(null, user);
});
robertklep
fuente
2
Trabajó para mi. ¿Por qué no tengo que usar la parte 'id' como está escrita en todas partes?
schlenger
9
@schlenger dependería de cómo implemente la serialización. A veces, se serializa por ID de usuario, lo que significa que la serializeUserfunción almacena solo la ID de usuario en la sesión y deserializeUserusa esa ID para recuperar los datos de usuario de una base de datos (por ejemplo). Esto es para evitar que el almacenamiento de la sesión contenga los datos reales del usuario.
robertklep
+1 comentario de @robertklep. Siempre evitaría serializar la información del usuario, pero solo las identificaciones (por razones de hincha / perf personalmente).
electblake
2
@robertklep No quiero almacenarlo en sesión. Estoy usando JWT. ¿Se requiere serializeUser / deserializeUser? Quiero una no sesión. Estoy usando JWT
Internial
@Internial no está seguro si los necesita, pero sería algo fácil de probar.
robertklep
44

Si decide no usar sesiones, puede configurar la sesión en falso

app.post('/login', passport.authenticate('local', {
  successRedirect: '/accessed',
  failureRedirect: '/access',
  session: false
}));
Kevin
fuente
Pero eso no apagará la sesión en todos los demás puntos finales (donde tampoco quiero ninguna sesión)
jayarjo
17

Parece que te perdiste una parte de la configuración de passportjs, específicamente estos dos métodos:

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

Agregué un poco sobre ._idvs. .idpero este fragmento es de la sección Configurar de documentos, dale otra lectura y buena suerte :)

electblake
fuente
2

Aquí, una manera funcional pero aún perezosa de usar sesiones y aún "serializar" los valores.

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

en caso de errores extraños solo pregúntese: "¿Realmente configuro '_id' en mi objeto de usuario?" - En la mayoría de los casos no lo haces. Entonces use un atributo apropiado como clave.

Ganku Caelestis
fuente
0

Usando Promise con serializeUser y 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}`);
    });
});

Consulte mi repositorio de github para ver un ejemplo de código completo sobre cómo resolver este problema.

Isak La Fleur
fuente
-1

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

si err tiene que devolver "false" err {return done (null, req.flash ('megsign', 'Nombre de usuario ya existe #! #'));} true {return done (null, false, req.flash (' megsign ',' El nombre de usuario ya existe #! # '));}

annguyen
fuente