【问题标题】:Passport.js - Error: failed to serialize user into sessionPassport.js - 错误:无法将用户序列化到会话中
【发布时间】:2013-11-25 18:16:09
【问题描述】:

我遇到了 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');

}();

谢谢。

【问题讨论】:

    标签: node.js express login passport.js passport-local


    【解决方案1】:

    您似乎没有实现passport.serializeUserpassport.deserializeUser。尝试添加:

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

    【讨论】:

    • 为我工作。为什么我不必使用其他地方写的“id”部分?
    • @schlenger 这取决于您如何实现序列化。有时您按用户 ID 进行序列化,这意味着 serializeUser 函数仅在会话中存储用户 ID,deserializeUser 使用该 ID 从数据库中检索用户数据(例如)。这是为了防止会话存储本身包含实际的用户数据。
    • +1 @robertklep 评论。我总是避免序列化用户信息,而只序列化 id(出于个人膨胀/性能原因)。
    • @robertklep 我不想将它存储在会话中。我正在使用智威汤逊。是否需要 serializeUser/deserializeUser?我想要一个没有会话。我正在使用智威汤逊
    • @Internal 不确定您是否需要它们,但测试起来很容易。
    【解决方案2】:

    听起来你错过了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);
      });
    });
    

    我添加了一些关于 ._id.id 的内容,但这个 sn-p 来自文档的 Configure Section,再读一遍,祝你好运:)

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • 但这不会关闭所有其他端点上的会话(我也不需要任何会话)
      【解决方案4】:

      这是一种有效但仍然懒惰的方式来使用会话并仍然“序列化”值。

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

      以防万一或奇怪的错误问自己:“我会在我的用户对象中设置'_id'吗?” - 在大多数情况下你没有。所以使用适当的属性作为键。

      【讨论】:

        【解决方案5】:

        将 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 repo 了解如何解决此问题的完整代码示例。

        【讨论】:

          【解决方案6】:

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

          如果出错,您必须返回“false” err {return done(null, req.flash('megsign', '用户名已经存在#!#'));} true {return done(null, false, req.flash('megsign', '用户名已经存在#!#'));}

          【讨论】:

            【解决方案7】:

            你错过了这个代码:

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

            详情请查看http://www.passportjs.org/docs/configure/的会话部分

            【讨论】:

              【解决方案8】:

              将此代码用于您的 server.js 文件中,您可以在其中发出 get 或 post 请求。

                app.get('/auth/facebook/callback',passport.authenticate('facebook',{
                  successRedirect:'/profile',
                  failureRdirect:'/',
                  session: false
              }))
              

              【讨论】:

                【解决方案9】:

                确保在获取用户数据时使用了 async 和 await。

                passport.serializeUser((user, done) => {
                   done(null, user.id);
                });
                
                passport.deserializeUser(async (id, done) => {
                  const USER = await User.findById(id);
                  done(null, USER);
                });
                
                passport.use(
                  new GoogleStrategy(
                    {
                      // options for google strategy
                      clientID: keys.google.clientID,
                      clientSecret: keys.google.clientSecret,
                      callbackURL: "/auth/google/redirect",
                    },
                    async (accessToken, refreshToken, profile, done) => {
                      //   passport callback function
                
                      //   check if user already exist in our db
                      const oldUser = await User.findOne({ googleId: profile.id });
                      if (oldUser) {
                        return done(null, oldUser);
                      } else {
                        const newUser = await new User({
                          username: profile.displayName,
                          googleId: profile.id,
                        }).save();
                        return done(null, newUser);
                      }
                    }
                  )
                );
                

                【讨论】:

                  【解决方案10】:

                  我今天发现的另一个普遍原因是,如果您使用的是标准包,例如护照、passport-local、passport-local-mongoose 和 express-session,并且您已经在您正在登录的会话中在然后您终止服务器并再次重新启动,您将在登录时处于同一会话中,在该会话中浏览器不断加载而没有响应,并且您会收到“无法将用户序列化到会话中”的错误。

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 2018-10-22
                    • 2021-03-14
                    • 2020-02-04
                    • 2019-03-26
                    • 1970-01-01
                    • 2013-02-27
                    • 2021-12-14
                    • 2012-09-19
                    相关资源
                    最近更新 更多