Passport.js-错误:无法将用户序列化为会话


179

我在Passport.js模块和Express.js中遇到问题。

这是我的代码,我只想使用硬编码登录名进行首次尝试。

我总是收到消息:

我搜索了很多东西,然后在stackoverflow中找到了一些帖子,但是我没有失败。

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

我的代码如下所示。

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

}();

谢谢。

Answers:


360

看来您没有实现passport.serializeUserpassport.deserializeUser。尝试添加以下内容:

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

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

2
为我工作。为什么我不必使用其他地方写的“ id”部分?
schlenger 2014年

9
@schlenger,这取决于您如何实现序列化。有时,您通过用户ID进行序列化,这意味着该serializeUser函数仅在会话中存储用户ID,并deserializeUser使用该ID从数据库中检索用户数据(例如)。这是为了防止会话存储包含实际的用户数据本身。
robertklep

+1 @robertklep评论。我总是避免序列化用户信息,而只序列化ID(出于个人膨胀/性能原因)。
electblake

2
@robertklep我不想将其存储在会话中。我正在使用JWT。是否需要serializeUser / deserializeUser?我不希望开会。我正在使用JWT
Internial '17

@Internial不确定是否需要它们,但是这很容易测试。
robertklep

44

如果您决定不使用会话,则可以将会话设置为false

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

但这不会关闭所有其他终结点计算机上的会话(我也不想进行任何会话)
jayarjo

17

听起来您好像错过了passportjs设置的一部分,特别是以下两种方法:

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

我添加了关于._idvs.的内容,.id但此代码段来自docs 的Configure部分,请多加阅读并祝您好运:)


2

这是使用会话并且仍然“串行化”值的一种可行但仍然很懒的方法。

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

如果出现错误或奇怪的错误,请问自己:“我是否在用户对象中rlly设置了'_id'?” -在大多数情况下,您不这样做。因此,请使用适当的属性作为键。


0

将Promise与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}`);
    });
});

请参阅我的github存储库以获取有关如何解决此问题的完整代码示例。


-1

在password.use('local-login'...)/或/('local-singup'...)

如果错误,则必须返回“假”错误{返回完成(空,req.flash('megsign','用户名已经存在!!#')))}} {正确megsign','用户名已经存在#!#'));}

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.