如何移除用户列表,改用Mongoose+MongoDB实现Passport.js登录注册?
解决方案:从数组存储迁移到MongoDB+Mongoose的Passport.js适配
核心修改步骤
- 替换Passport的用户查询逻辑为Mongoose异步操作
原代码中基于数组的同步查找无法适配数据库的异步操作,需要替换为Mongoose的查询方法。 - 移除内存中的
users数组
彻底废弃原数组存储,所有用户操作直接对接MongoDB。 - 修正Passport认证流程的异步处理
数据库查询是异步的,必须在认证和反序列化流程中等待查询结果。 - 优化用户模型(可选但推荐)
给邮箱字段添加唯一约束,避免重复注册;可考虑使用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
相关产品推荐
相关产品推荐

