MongoDB中OTP验证码无故提前删除的解决方法求助
解决OTP在到期前被错误删除的问题
核心问题定位:createdAt默认值错误
你的Schema中createdAt的default设置为Date.now(),这会导致所有新创建的文档都使用Schema定义时刻的固定时间,而非文档实际创建时的当前时间。如果Schema在服务器启动时加载,后续生成的OTP文档的createdAt都会是服务器启动时间:若服务器已运行超过1小时,新OTP会被立即清理;若服务器刚启动不久,新OTP的过期时间也会被提前,大概率触发误删除。
修复代码
将createdAt的默认值改为Date.now(去掉括号),确保每次创建文档时取当前时间:
const EmailVerificationTokenSchema = mongoose.Schema({ owner: { type: mongoose.Schema.Types.ObjectId, ref: "User", required: true, }, token: { type: String, required: true, }, createdAt: { type: Date, expires: 3600, default: Date.now, // 去掉括号,改为函数引用 }, });
其他排查与优化方向
- 规范重复OTP请求处理:若用户多次申请OTP,需确保创建新token前先删除该用户的旧token,避免新旧token冲突导致的误删逻辑。
- 验证TTL索引有效性:在MongoDB Shell中执行
db.emailverificationtokens.getIndexes(),确认createdAt字段的TTL索引存在且过期时间为3600秒。若索引缺失,手动创建:db.emailverificationtokens.createIndex({ createdAt: 1 }, { expireAfterSeconds: 3600 }) - 排查文档删除逻辑:检查项目中所有操作
EmailVerificationToken模型的代码,确认验证成功、定时任务等场景下没有误删未过期token的逻辑。 - 监控pre-save钩子:在
pre("save")钩子中添加日志,确认钩子未异常修改createdAt字段或导致文档保存失败。
内容的提问来源于stack exchange,提问作者JavierMalaguita
相关产品推荐
相关产品推荐

