MongoDB中注册页面点击注册按钮出现重复邮箱数据问题
邮箱重复存储问题的解决方法
问题说明
每次使用同一邮箱完成注册时,该邮箱对应的用户数据仍会被重复写入MongoDB,即便已在Schema的email字段设置unique: true,不符合不重复存储的预期。
核心原因及解决步骤
1. 唯一索引未生效
Mongoose的unique: true仅为Schema层面的声明,若集合已提前创建且未配置唯一索引,该设置不会自动生效。需手动创建索引:
// 在UserSchema定义后添加索引配置 UserSchema.index({ email: 1 }, { unique: true });
或者直接在MongoDB控制台执行命令(执行前需清理已存在的重复邮箱数据,否则索引创建失败):
db.users.createIndex({ email: 1 }, { unique: true })
2. 未捕获重复键错误
即便索引生效,注册逻辑若未处理数据库返回的重复键错误,前端无法收到有效反馈。需在注册代码中添加错误捕获:
try { const newUser = await User.create(userData); // 注册成功后的逻辑 } catch (error) { // 错误码11000对应MongoDB唯一键冲突 if (error.code === 11000) { throw new Error('该邮箱已被注册'); } // 处理其他类型错误 throw error; }
3. 密码验证逻辑错误
原代码中密码验证仅返回false未抛出错误,Mongoose无法正确识别验证失败。修正如下:
password: { type: String, required: true, validate: pass => { if (!pass?.length || pass.length < 5) { throw new Error('密码至少需要5个字符'); } }, }
修正后的完整User.js代码
import bcrypt from 'bcrypt'; import { Schema, model, models } from "mongoose"; const UserSchema = new Schema({ email: { type: String, required: true, unique: true }, password: { type: String, required: true, validate: pass => { if (!pass?.length || pass.length < 5) { throw new Error('密码至少需要5个字符'); } }, }, }, { timestamps: true }); // 创建邮箱唯一索引 UserSchema.index({ email: 1 }, { unique: true }); UserSchema.post('validate', function (user) { const notHashedPassword = user.password; const salt = bcrypt.genSaltSync(10); user.password = bcrypt.hashSync(notHashedPassword, salt); }); const User = models.User || model('User', UserSchema); export default User;
内容的提问来源于stack exchange,提问作者Akbar Pratama
相关产品推荐
相关产品推荐

