Node.js用户注册时邮箱查重功能实现及代码优化咨询
Node.js注册时邮箱重复验证实现及代码优化
一、邮箱已存在验证的实现步骤
在用户注册提交时,先查询数据库中是否存在相同邮箱,再执行插入操作:
- 在
saveRegister方法中,先执行查询邮箱是否存在的SQL语句 - 根据查询结果判断:
- 若邮箱已存在,通过flash返回错误提示并跳转回注册页
- 若邮箱不存在,再执行用户数据插入操作
二、现有代码的优化点
- 错误处理不严谨:直接
throw err会导致服务器崩溃,需改为捕获错误并返回用户友好提示 - 数据库连接释放时机错误:
connection.release()放在回调外会导致连接提前释放,需移至查询回调内部 - 硬编码URL:
http://localhost:5050/应放在配置文件中,避免硬编码 - 表单验证薄弱:仅判断字段非空,缺少邮箱格式校验
- 密码哈希方式建议:建议使用专门的加密库(如
bcrypt)而非数据库函数,更安全且便于维护 - 视图渲染错误:
formRegister中渲染login视图,但注释说明是register.ejs,存在逻辑矛盾 - 变量命名不规范:
pass应改为password,与字段名保持一致
三、修改后的完整代码
router_register.js(逻辑无问题,保留原结构)
//router_register.js // 定义express路由 const router = require('express').Router(); // 引入register控制器 const registerController = require('../controllers').register; // 引入登录状态验证中间件 const verifyUser = require('../configs/verify'); // 显示注册表单路由,仅未登录用户可访问 router.get('/', verifyUser.isLogout, registerController.formRegister); // 处理注册提交路由,仅未登录用户可访问 router.post('/save', verifyUser.isLogout, registerController.saveRegister); module.exports = router;
controller_register.js(添加邮箱验证+优化后)
//controller_register const config = require('../configs/database'); const mysql = require('mysql'); const pool = mysql.createPool(config); // 可选:安装bcrypt后替换SHA2,执行npm install bcrypt // const bcrypt = require('bcrypt'); // const saltRounds = 10; pool.on('error', (err)=> { console.error('数据库连接池错误:', err); }); module.exports = { formRegister(req, res) { // 修正视图渲染,改为register.ejs res.render("register", { // 建议从配置文件读取baseURL,或用环境变量 url: process.env.BASE_URL || 'http://localhost:5050/', // 传递flash消息到视图 messages: req.flash() }); }, saveRegister(req, res) { let username = req.body.username; let email = req.body.email; let password = req.body.password; // 修正变量名,与表单字段一致 // 增强表单验证:邮箱格式校验+字段非空 const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (!username || !email || !password || !emailRegex.test(email)) { req.flash('color', 'danger'); req.flash('status', '错误..'); req.flash('message', '请填写完整信息或输入正确格式的邮箱'); return res.redirect('/register'); // 跳转回注册页而非登录页 } pool.getConnection(function(err, connection) { if (err) { console.error('获取数据库连接失败:', err); req.flash('color', 'danger'); req.flash('status', '错误..'); req.flash('message', '服务器连接失败,请稍后重试'); return res.redirect('/register'); } // 查询邮箱是否已存在 connection.query( `SELECT user_email FROM table_user WHERE user_email = ?`, [email], function (error, results) { if (error) { console.error('查询邮箱失败:', error); req.flash('color', 'danger'); req.flash('message', '验证邮箱失败,请稍后重试'); connection.release(); // 释放连接 return res.redirect('/register'); } // 邮箱已存在的情况 if (results.length > 0) { req.flash('color', 'danger'); req.flash('status', '提示..'); req.flash('message', '该邮箱已被注册,请更换邮箱'); connection.release(); return res.redirect('/register'); } // 邮箱不存在,执行插入操作 // 可选:使用bcrypt哈希密码(推荐) // bcrypt.hash(password, saltRounds, function(bcryptErr, hash) { // if (bcryptErr) throw bcryptErr; // connection.query( // `INSERT INTO table_user (user_name, user_email, user_password) VALUES (?,?,?)`, // [username, email, hash], function (insertError, insertResults) { // // 插入逻辑处理 // } // ) // }) // 原有SHA2哈希方式(建议替换为bcrypt) connection.query( `INSERT INTO table_user (user_name, user_email, user_password) VALUES (?,?,SHA2(?,512))`, [username, email, password], function (insertError, insertResults) { connection.release(); // 插入完成后释放连接 if (insertError) { console.error('注册插入失败:', insertError); req.flash('color', 'danger'); req.flash('message', '注册失败,请稍后重试'); return res.redirect('/register'); } req.flash('color', 'success'); req.flash('status', '成功..'); req.flash('message', '注册成功,请登录'); res.redirect('/login'); } ); } ); }) } }
补充说明
- 若使用
bcrypt,需先执行npm install bcrypt安装依赖,替换原有数据库哈希逻辑 - 建议在项目根目录创建
.env文件存储BASE_URL等配置,使用dotenv库读取 - 视图层(register.ejs)需添加flash消息的展示逻辑,方便用户看到提示
内容的提问来源于stack exchange,提问作者Mighty 27_
相关产品推荐
相关产品推荐

