重新启动服务器后,为什么password.js无法反序列化用户?

问题描述

问题:我正在使用passport.js来验证用户身份。一切正常,他们可以登录。其ID序列化到会话中,并且在后续请求中访问req.user时也进行反序列化。但是,当我关闭服务器或重新启动服务器时,请转到任何路由。它给我一个错误,“无法反序列化用户出会话”。我注意到,当我从数据库删除用户会话时(我正在使用云托管的mongo-db),我必须再次登录才能正常工作,直到再次重启服务器(这在开发中很常见)。我无法删除会话,一次又一次,然后再次登录。那是一个巨大的麻烦。有谁知道可能是什么原因造成的?

修改 这是我使用的代码

passport.js策略文件

const passport = require('passport');
const User = require('./../models/user.js');
const bcrypt = require('bcrypt');

const LocalStrategy = require('passport-local').Strategy;
passport.use(new LocalStrategy({usernameField : 'email'},(email,password,done) => {
  //see if the user with such username exists
  User.findOne({email},(err,user) => {
    if (err) {
      return done(err,false,{message : "Something went wrong."});
    }

    if(!user) {
      return done(null,{message : "No such user exists."});
    }

    //check if the password matches
    bcrypt.compare(password,user.password).then(match => {
      if(!match) {
        return done(null,{message : "Password and email doesn't match."});
      }
      done(null,user,{message : "Log in successful"});
    }).catch(err => {
      done(err,{message : "Something went wrong. Try again."});
    });

    passport.serializeUser((user,done) => {
      done(null,user._id,);
    });

    passport.deserializeUser((id,done) => {
      User.findById(id,user) => {
        done(err,user);
      })
    });
  });
})
);

会话配置:

app.use(session({
  secret : process.env.COOKIE_SECRET,name : "PizzaCartSession",resave : false,store : mongoStore,saveUninitialized : false,cookie : {maxAge : 1000 * 60 * 60,} // 4 hours
}));

解决方法

如果我的回答有用,请添加投票:D
我和你有同样的问题。我花了 3-4 个小时来解决这个问题。
我不知道为什么但是很多教程在Local-Strategy中添加了serialize和deserialize - 这是错误的!!! Serializing and deserializing属于passport instance所以我们可以在local-strategy之前或之后进行. 记住express-session之后和passport.initialize() & passport.session()之前添加所有通行证配置(本地策略、序列化和反序列化)。

Error: failed to deserialize user out of session - 登录有效,因为您启动了本地策略,您已经实现了序列化和反序列化,并且服务器知道他们必须做什么。当您在 FrontEnd 中从 cookie 检查活动会话时,您没有启动本地策略,服务器也不知道反序列化是什么。

代码

  1. 文件:'./server.js'
// Express Session
app.use(
  session({
    secret: process.env.secret,saveUninitialized: true,resave: false,// Default store is only for debug - Save session in MongoDB
    store: new MongoStore({
      mongooseConnection: mongoose.connection,collection: 'sessions',}),cookie: {
      maxAge: 1000 * 60 * 60 * 24,// one day
    },})
);

// Added & Init Passport Local Config for entire App
require('./config/passportConfig')(passport);
// Init passport & session
app.use(passport.initialize());
app.use(passport.session());
  1. 文件:'./config/passportConfig'
const User = require('../models/User');
const LocalStrategy = require('passport-local').Strategy;

// Why we pass instances of passport to functions when we call it  ??
// Bc we want the same instane of passort in our entire appliaction
module.exports = (passport) => {
//----------Start Local-Strategy----------//
  passport.use(
    new LocalStrategy(
      { usernameField: 'email' },// we show that we have an email field like username
      async (email,password,done) => {
        try {
          // 1. Looking for User & his paassword in DB by email
          const user = await User.findOne({ email }).select('+password');
          // 2. Checking if user exists
          if (!user) {
            return done(null,false,{
              // If not exist stop function and return msg to login control
              msg: 'That email is not registered',});
          }
          // 3. Comparing password from form with password from DB
          // Using method from UserSchema
          const isMatch = await user.matchPassword(password);
          if (isMatch) {
            // If is match stop function adn return user to login control
            return done(null,user,{ msg: 'User Found' });
          } else {
            // If not exist stop function and return msg to login control
            return done(null,{ msg: 'Incorrect Password' });
          }
        } catch (error) {
          // If error with connection with DB return msg  to login control
          console.error(error);
          return done(null,{ msg: 'Server Error' });
        }
      }
    )
  );
//----------End of Local-Strategy----------//
  // Serialize only user id
  passport.serializeUser(function (user,done) {
    done(null,user.id);
  });
  // Deserialize by user id
  passport.deserializeUser((id,done) => {
    User.findById(id)
      .then((user) => {
        done(null,user);
      })
      .catch((err) => done(err));
  });
};

如果您想要更多代码check my repo。前端 - React,后端 - Express。