Passport.js - Erro: falha ao serializar o usuário na sessão


179

Eu tive um problema com o módulo Passport.js e o Express.js.

Este é o meu código e eu só quero usar um login codificado na primeira tentativa.

Eu sempre recebo a mensagem:

Pesquisei bastante e encontrei algumas postagens no stackoverflow, mas não obtive a falha.

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

Meu código fica assim.

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

}();

Obrigado.

Respostas:


362

Parece que você não implementou passport.serializeUsere passport.deserializeUser. Tente adicionar isto:

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

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

2
Trabalhou para mim. Por que não preciso usar a parte 'id' como escrita em qualquer outro lugar?
Schlenger

9
@ schlenger, depende de como você implementa a serialização. Às vezes, você serializa pelo ID do usuário, o que significa que a serializeUserfunção armazena apenas o ID do usuário na sessão e deserializeUserusa esse ID para recuperar os dados do usuário de um banco de dados (por exemplo). Isso evita que o armazenamento da sessão contenha os dados reais do usuário.
robertklep

Marcar um comentário com @robertklep. Eu sempre evitava serializar as informações do usuário, mas apenas os IDs (por razões de inchaço / perf pessoalmente).
Electblake

2
@robertklep Não quero armazená-lo em sessão. Estou usando o JWT. SerializeUser / deserializeUser é necessário? Eu quero uma sessão sem. Eu estou usando JWT
Internial 30/10

@ International não tem certeza se você precisa deles, mas seria uma coisa fácil de testar.
Robertklep

44

Se você decidir não usar sessões, poderá definir a sessão como false

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

Mas isso não vai desligar sessão em todos os outros pontos de extremidade (onde eu também não quero qualquer sessão)
jayarjo

17

Parece que você perdeu uma parte da configuração do passportjs, especificamente esses dois 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);
  });
});

Eu adicionei um pouco sobre ._idvs., .idmas esse trecho é da seção de configuração dos documentos, faça outra leitura e boa sorte :)


2

Aqui, uma maneira prática, mas ainda preguiçosa, de usar sessões e ainda "serializar" os 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]);
});

no caso de erros estranhos, pergunte a si mesmo: "Eu realmente defino '_id' no meu objeto de usuário?" - na maioria dos casos você não. Portanto, use um atributo apropriado como chave.


0

Usando o Promise com 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}`);
    });
});

Consulte meu repositório do github para obter um exemplo de código completo de como resolver esse problema.


-1

no passport.use ('local-login' ...) / ou / ('local-singup' ...)

se err você tem que retornar "false" err {return done (null, req.flash ('megsign', 'Nome de usuário já existe #! #'));} true {return done (null, false, req.flash (' megsign ',' Nome de usuário já existe #! # '));}

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.