You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

passport文件无法读取schema文件compare密码函数,输入账号密码后程序崩溃

问题原因
  • 最常见的原因是comparePassword实例方法挂载时机错误:Mongoose要求实例方法必须在mongoose.model()编译模型之前挂载到Schema上,如果先编译导出模型再定义方法,方法不会被挂载到模型实例上,调用时会抛出undefined错误导致程序崩溃。
  • 第二个原因是passport登录逻辑未做非空校验:如果输入的邮箱在库中不存在,findOne查询会返回null,直接调用null.comparePassword也会触发报错。
  • 第三个原因是方法名拼写不一致:注意JavaScript大小写敏感,passport中调用的方法名需要和Schema上定义的方法名完全匹配。
解决方案
  1. 调整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)
  1. 优化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)
    }
  }
))
  1. 核对两边的方法名拼写,确认没有大小写或字符拼写错误。

内容的提问来源于stack exchange,提问作者Mohamed Aboda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 10:24:01