passport文件无法读取schema文件compare密码函数,输入账号密码后程序崩溃
问题原因
- 最常见的原因是
comparePassword实例方法挂载时机错误:Mongoose要求实例方法必须在mongoose.model()编译模型之前挂载到Schema上,如果先编译导出模型再定义方法,方法不会被挂载到模型实例上,调用时会抛出undefined错误导致程序崩溃。 - 第二个原因是passport登录逻辑未做非空校验:如果输入的邮箱在库中不存在,
findOne查询会返回null,直接调用null.comparePassword也会触发报错。 - 第三个原因是方法名拼写不一致:注意JavaScript大小写敏感,passport中调用的方法名需要和Schema上定义的方法名完全匹配。
解决方案
- 调整Schema文件的代码顺序,确保先定义方法再编译模型,参考代码:
const mongoose = require('mongoose') const bcrypt = require('bcryptjs') const userSchema = new mongoose.Schema({ email: { type: String, required: true, unique: true }, password: { type: String, required: true } }) // 必须在model编译前定义实例方法 userSchema.methods.comparePassword = async function (inputPassword) { return bcrypt.compare(inputPassword, this.password) } // 最后编译导出模型 module.exports = mongoose.model('User', userSchema)
- 优化passport逻辑,增加用户存在性校验:
const passport = require('passport') const LocalStrategy = require('passport-local').Strategy const User = require('./models/User') // 确认路径正确 passport.use(new LocalStrategy( { usernameField: 'email' }, async (email, password, done) => { try { // 查询用户 const user = await User.findOne({ email: email }) // 先判断用户是否存在 if (!user) { return done(null, false, { message: '邮箱未注册' }) } // 再比对密码 const isMatch = await user.comparePassword(password) if (!isMatch) { return done(null, false, { message: '密码错误' }) } return done(null, user) } catch (err) { return done(err) } } ))
- 核对两边的方法名拼写,确认没有大小写或字符拼写错误。
内容的提问来源于stack exchange,提问作者Mohamed Aboda
相关产品推荐
相关产品推荐

