如何为Node.js验证码设置过期时间并10分钟后从数据库删除
实现验证码10分钟过期自动删除的方案
步骤1:修改数据库表结构
首先给verifications表添加存储过期时间的字段:
ALTER TABLE verifications ADD COLUMN expires_at DATETIME NOT NULL;
步骤2:修改验证码生成与存储逻辑
生成验证码时计算10分钟后的过期时间,并存入数据库,同时修复原代码的SQL注入风险:
app.post("/sendforgetpassword", async (req, res) => { const email = req.body.email; // 计算10分钟后的过期时间 const expiresAt = new Date(Date.now() + 10 * 60 * 1000); const fourcode = Math.floor(1000 + Math.random() * 9000); // 参数化查询避免SQL注入 database.query('SELECT * FROM verifications WHERE email = ?', [email], function(err, result) { if (err) { console.log(err); return res.send('服务器出错,请稍后重试'); } if (result.length > 0) { const existingRecord = result[0]; // 检查已有验证码是否未过期 if (existingRecord.code !== null && new Date(existingRecord.expires_at) > Date.now()) { return res.send('验证码已发送至您的邮箱,请查收'); } // 发送邮件 const sent = sendEmail(email, fourcode); if (sent !== '0') { const updateData = { code: fourcode, expires_at: expiresAt }; // 参数化更新数据 database.query('UPDATE verifications SET ? WHERE email = ?', [updateData, email], function(err) { if (err) { console.log(err); return res.send('服务器出错,请稍后重试'); } res.send('验证码已发送至您的邮箱,请查收'); }); } else { res.send('发送失败,请稍后重试'); } } else { res.send('该邮箱未注册'); } }); });
步骤3:自动删除过期验证码
两种可靠方案可选:
方案A:数据库定时任务(推荐)
利用数据库事件调度定期清理过期记录,以MySQL为例:
- 开启事件调度器:
SET GLOBAL event_scheduler = ON;
- 创建每分钟执行的清理事件:
CREATE EVENT IF NOT EXISTS clean_expired_verifications ON SCHEDULE EVERY 1 MINUTE DO DELETE FROM verifications WHERE expires_at < NOW() AND code IS NOT NULL;
方案B:验证时检查并清理
在验证码验证接口中,先判断是否过期,过期则清空验证码:
app.post("/verifyforgetpassword", async (req, res) => { const { email, code } = req.body; database.query('SELECT * FROM verifications WHERE email = ?', [email], function(err, result) { if (err || result.length === 0) { return res.send('验证失败,请检查邮箱或重新获取验证码'); } const verification = result[0]; // 检查验证码是否过期 if (new Date(verification.expires_at) < Date.now()) { // 过期后清空验证码 database.query('UPDATE verifications SET code = NULL, expires_at = NULL WHERE email = ?', [email], function(err) { if (err) console.log(err); }); return res.send('验证码已过期,请重新获取'); } // 验证验证码正确性 if (verification.code == code) { res.send('验证成功'); } else { res.send('验证码错误'); } }); });
额外优化提示
- 原代码中
database和connection对象混用,建议统一使用一个数据库连接实例。 - 所有SQL操作必须使用参数化查询,杜绝SQL注入风险。
sendEmail函数建议改为异步Promise实现,避免同步阻塞。
内容的提问来源于stack exchange,提问作者husam
相关产品推荐
相关产品推荐

