【问题标题】:passport.deserializeUser only working when not passing 'id' through 'getUserById'passport.deserializeUser 仅在不通过 'getUserById' 传递 'id' 时工作
【发布时间】:2021-04-20 22:19:35
【问题描述】:

起初我的代码的序列化/反序列化部分看起来像这样

passport.use(new LocalStrategy({ usernameField: 'email' }, authenticateUser))
passport.serializeUser((user, done) => done(null, user.id))
passport.deserializeUser((id, done) => {
   return done(null, getUserById(id))
});

但是在我登录req.user 后返回Promise { <pending> }。所以我然后尝试将我的代码更改为这个

passport.use(new LocalStrategy({ usernameField: 'email' }, authenticateUser))
passport.serializeUser((user, done) => done(null, user.id))
passport.deserializeUser((id, done) => {
   getUserById(id).then(user => {
      done(null, user);
   }).catch(err => {
   console.log(err)
      done(err);
   });
})

我希望将.then().catch() 附加到promise 可以解决问题,但当时我无法登录,我意识到打印getUserById(id) 返回null。在搞砸并尝试了不同的事情之后,我意识到当我简单地不将id 传递给getUserById() 时,代码可以按预期工作。但这肯定不是好事吧?

旁注:打印 id 总是返回登录用户 id

这是我剩下的初始化函数

function initialize(passport, getUserByEmail, getUserById) {
    const authenticateUser = async (email, password, done) => {
        const user = await getUserByEmail(email)
        console.log(email)
        if (user == null) {
        return done(null, false, { message: 'Incorrect email or password' })
    }
    try {
        if (await bcrypt.compare(password, user.password)) {
        return done(null, user)
    } else {
        return done(null, false, { message: 'Incorrect email or password' })
    }
    } catch (e) {
        return done(e)
    }
}

最后,我在 index.js 中定义电子邮件和 ID

const initializePassport = require('../passport-config')
initializePassport(
    passport,
    async (email) => await User.findOne({email: email}),
    async (id) => await User.findOne({id: id})
)

如果有人能指出为什么我在尝试以正确的方式反序列化我的用户时遇到此问题,我将不胜感激。这是我第一次做任何类型的后端编码,即使只是走到这一步也已经是一段相当长的旅程了。

【问题讨论】:

  • 听起来您遇到了getUserById 的问题,而这又影响了deserializeUser。你能分享getUserById 的代码还是从猫鼬那里拉出来?
  • 是的,我正在使用猫鼬。我有一个userSchema,它只需要一个姓名、电子邮件和密码@jasonandmonte

标签: javascript node.js express passport.js


【解决方案1】:

看起来您正在使用User 对象来执行查询,但在deserializeUser 中您只是使用了一个名为getUserById 的函数。我不清楚这是否是您的用户模型的自定义包装器,但要获取 id,您可以使用.findById

我建议更新块以使用用户对象来查询数据库。你也可以通过使用 async/await 来让事情变得更平坦,但它也应该与 .then 一起使用。

例子:

passport.deserializeUser(async (id, done) => {
  const user = await User.findById(id);
   return done(null, user);
});

型号参考:https://mongoosejs.com/docs/api.html#model_Model.findById

【讨论】:

  • 非常感谢!这很完美。我有点尴尬,这是一件很愚蠢的事情,以至于我弄错了,但我想这是我在学习在本地存储用户而不是使用猫鼬哈哈的教程时应得的。我最初也在使用 async/await,但一位朋友告诉我 .then().catch() 更适合捕获对我来说有意义的错误
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多