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

如何移除用户列表,改用Mongoose+MongoDB实现Passport.js登录注册?

解决方案:从数组存储迁移到MongoDB+Mongoose的Passport.js适配

核心修改步骤

  1. 替换Passport的用户查询逻辑为Mongoose异步操作
    原代码中基于数组的同步查找无法适配数据库的异步操作,需要替换为Mongoose的查询方法。
  2. 移除内存中的users数组
    彻底废弃原数组存储,所有用户操作直接对接MongoDB。
  3. 修正Passport认证流程的异步处理
    数据库查询是异步的,必须在认证和反序列化流程中等待查询结果。
  4. 优化用户模型(可选但推荐)
    给邮箱字段添加唯一约束,避免重复注册;可考虑使用Mongoose自动生成的_id替代自定义id字段简化逻辑。

修改后的关键代码片段

server.js(关键修改部分)

// 移除内存数组:const users = []

// 修改Passport初始化的查询函数为异步Mongoose查询
const initializePassport = require('./passport-config')
initializePassport(
  passport,
  async (email) => await User.findOne({ email }), // 按邮箱查询用户
  async (id) => await User.findOne({ id }) // 按自定义id查询用户
)

// 注册路由:移除数组推送,简化数据库操作
app.post('/register', checkNotAuthenticated, async (req, res) => {
  try {
    const hashedPassword = await bcrypt.hash(req.body.password, 10)
    // User.create已自动完成保存,无需额外调用save()
    await User.create({ 
      id: Date.now().toString(), 
      name: req.body.name, 
      email: req.body.email, 
      password: hashedPassword 
    })
    res.redirect('/login')
  } catch (err) {
    console.error(err) // 打印错误便于调试
    res.redirect('/register')
  }
})

passport-config.js(修正异步处理)

const LocalStrategy = require('passport-local').Strategy
const bcrypt = require('bcrypt')

function initialize(passport, getUserByEmail, getUserById) {
  const authenticateUser = async (email, password, done) => {
    // 等待异步查询结果
    const user = await getUserByEmail(email)
    if (user == null) {
      return done(null, false, { message: 'Nutzer mit dieser Mail nicht vorhanden' })
    }

    try {
      if (await bcrypt.compare(password, user.password)) {
        return done(null, user)
      } else {
        return done(null, false, { message: 'Passwort falsch' })
      }
    } catch (e) {
      return done(e)
    }
  }

  passport.use(new LocalStrategy({ usernameField: 'email' }, authenticateUser))
  passport.serializeUser((user, done) => done(null, user.id))
  // 反序列化时也要等待异步查询
  passport.deserializeUser(async (id, done) => {
    const user = await getUserById(id)
    return done(null, user)
  })
}

module.exports = initialize

优化后的User.js(可选)

添加邮箱唯一约束,避免重复注册:

const mongoose = require("mongoose")

const userSchema =  mongoose.Schema({
    id: String,
    name: String,
    email: { type: String, unique: true, required: true }, // 唯一且必填
    password: { type: String, required: true }
})

module.exports = mongoose.model("User", userSchema)

注意事项

  • 确保MongoDB服务正在运行,连接字符串mongodb://localhost/userdb正确。
  • 若使用邮箱唯一约束,注册重复邮箱时会抛出错误,可在catch块中添加flash消息提示用户。
  • 若想改用Mongoose默认的_id字段,需将序列化/反序列化的user.id改为user._id,同时注册时无需手动生成id。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 23:30:45