多Mongoose模型(User与Farmer)的序列化/反序列化异常及数据存储混淆问题求助
Mongoose模型(User与Farmer)的序列化/反序列化异常及数据存储混淆问题求助
嗨,刚接触开发遇到这种多模型的Passport序列化问题很正常,咱们一步步拆解解决:
首先说问题根源:你现在的代码里先后调用了passport.serializeUser(Farmer.serializeUser())和passport.serializeUser(User.serializeUser()),但Passport的序列化/反序列化函数是全局唯一的,后面的User序列化逻辑会直接覆盖前面Farmer的。这就导致不管你注册的是Farmer还是User,最终都会用User的规则去处理,自然会出现数据识别混乱、看起来像是都存进Users模型的问题。
接下来是具体解决方案,核心是自定义序列化和反序列化函数,把用户所属的模型类型也存在Session里,这样反序列化时就能明确知道该去哪个集合查数据:
第一步:给不同模型的Passport策略命名
因为你用了passport-local-mongoose,每个模型的登录策略是独立的,给它们起专属名字避免冲突:
const farmerSchema = new mongoose.Schema({ username: String, password: String }); farmerSchema.plugin(passportLocalMongoose); const Farmer = mongoose.model("Farmer", farmerSchema); // 给Farmer的本地策略命名为local-farmer passport.use('local-farmer', Farmer.createStrategy()); const userSchema = new mongoose.Schema({ username: String, password: String, pattam: [{ name: { type: String, unique: true }, latitude: String, longitude: String, pattamdetails: String, pattamamount: String, pattamimg: { data: Buffer, contenttype: String } }] }); userSchema.plugin(passportLocalMongoose); const User = mongoose.model("User", userSchema); // 给User的本地策略命名为local-user passport.use('local-user', User.createStrategy());
第二步:自定义序列化与反序列化函数
替换掉你原来重复的serializeUser和deserializeUser调用,改成下面的逻辑:
// 序列化:把用户ID和所属模型类型一起存入Session passport.serializeUser(function(user, done) { // 判断当前用户属于哪个模型 const modelType = user instanceof Farmer ? 'Farmer' : 'User'; done(null, { id: user._id, modelType: modelType }); }); // 反序列化:根据Session里的模型类型,去对应集合查询用户 passport.deserializeUser(function(sessionData, done) { // 选择对应的模型 const TargetModel = sessionData.modelType === 'Farmer' ? Farmer : User; // 根据ID查询用户 TargetModel.findById(sessionData.id, function(err, user) { done(err, user); }); });
第三步:登录路由指定对应策略(如果有登录接口)
如果你的项目有单独的登录路由,要明确指定用哪个策略验证,比如:
// 农民登录接口 app.post('/login-farmer', passport.authenticate('local-farmer'), function(req, res) { res.redirect('/farmersPage'); }); // 普通用户登录接口 app.post('/login-user', passport.authenticate('local-user'), function(req, res) { res.redirect('/usersPage'); });
最后验证数据存储
注册完成后,你可以去MongoDB数据库里检查:Farmer模型对应的数据会存在farmers集合(Mongoose默认会把模型名转复数),User的数据存在users集合,不会再出现全部进Users模型的情况了。
备注:内容来源于stack exchange,提问作者Sreekumar
相关产品推荐
相关产品推荐

