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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 04:16:13