passport.deserializeUser 仅在不通过 'id' 通过 'getUserById' 时有效
passport.deserializeUser only working when not passing 'id' through 'getUserById'
起初我代码的 serialize/deserialize 部分看起来像这样
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()
可以解决问题,但那时我无法登录,我意识到打印 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})
)
如果有人能指出为什么我在尝试以正确的方式反序列化我的用户时遇到这个问题,我将不胜感激。这是我第一次进行任何类型的后端编码,即使只是走到这一步也是一段漫长的旅程。
看起来您正在使用 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
起初我代码的 serialize/deserialize 部分看起来像这样
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()
可以解决问题,但那时我无法登录,我意识到打印 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
中定义电子邮件和 IDconst initializePassport = require('../passport-config')
initializePassport(
passport,
async (email) => await User.findOne({email: email}),
async (id) => await User.findOne({id: id})
)
如果有人能指出为什么我在尝试以正确的方式反序列化我的用户时遇到这个问题,我将不胜感激。这是我第一次进行任何类型的后端编码,即使只是走到这一步也是一段漫长的旅程。
看起来您正在使用 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