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

时间:2020-10-30 04:22:38

标签: node.js express passport.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, false, {message : "No such user exists."});
    }

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

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

    passport.deserializeUser((id, done) => {
      User.findById(id, (err, 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
}));

1 个答案:

答案 0 :(得分:0)

如果我的回答有用,请添加投票: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, false, { msg: 'Incorrect Password' });
          }
        } catch (error) {
          // If error with connection with DB return msg  to login control
          console.error(error);
          return done(null, false, { 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。