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

Node.js+Express项目中如何在verify函数中获取signup函数的提交数据

解决方案

我们需要在两个独立的HTTP请求(signup提交请求、verify提交请求)之间共享用户临时注册数据,最安全且易实现的方案是使用express-session存储未验证的注册信息和OTP数据。

实现步骤

第一步:安装并配置express-session

首先安装依赖包:

npm install express-session

在项目入口文件(通常是app.js/index.js)中添加session配置:

const session = require('express-session');
// 放在路由注册之前
app.use(session({
  secret: process.env.SESSION_SECRET, // 建议写在环境变量里,使用随机字符串
  resave: false,
  saveUninitialized: false,
  cookie: { 
    maxAge: 15 * 60 * 1000, // 15分钟有效期,和OTP过期时间对应
    httpOnly: true // 禁止前端JS读取,提升安全性
  }
}));

第二步:修改signup接口,存储临时数据到session

在发送OTP邮件成功后,把需要后续入库的注册数据、OTP、过期时间存入session:

// ... 原有signup逻辑不变
transporter.sendMail(mailOptions, function (error, info) {
  if (error) {
    console.log(error);
    return res.render("signup", { message: "验证码发送失败,请重试" });
  } else {
    console.log("Email sent: " + info.response);
    // 新增:存储临时注册数据到session
    req.session.tempUser = {
      name: name,
      email: email,
      password: hashedPassword,
      otp: OTP,
      otpExpire: Date.now() + 15 * 60 * 1000 // OTP 15分钟后过期
    };
    res.render("verify");
  }
});
// ... 原有逻辑不变

第三步:实现verify接口逻辑

从session中读取临时数据,校验OTP后入库:

exports.verify = async (req, res) => {
  try {
    // 1. 从session获取临时注册数据,没有则提示先完成注册第一步
    const tempUser = req.session.tempUser;
    if (!tempUser) {
      return res.render("signup", { message: "注册会话已过期,请重新注册" });
    }

    // 2. 校验OTP是否正确、是否过期
    const userInputOtp = req.body.otp; // 假设verify页面的OTP输入框name是otp
    if (userInputOtp !== tempUser.otp) {
      return res.render("verify", { message: "验证码错误,请重试" });
    }
    if (Date.now() > tempUser.otpExpire) {
      // 过期后清理session
      delete req.session.tempUser;
      return res.render("signup", { message: "验证码已过期,请重新注册" });
    }

    // 3. OTP校验通过,将用户数据入库
    await db.query(
      "INSERT INTO test (name, email, password) VALUES (?, ?, ?)",
      [tempUser.name, tempUser.email, tempUser.password]
    );

    // 4. 入库成功后清理临时session数据,跳转到登录页
    delete req.session.tempUser;
    res.render("login", { message: "邮箱验证成功,请登录" });
  } catch (error) {
    console.log(error);
    res.render("verify", { message: "验证失败,请重试" });
  }
};

注意事项

  • 不推荐把注册数据放到verify页面的隐藏表单域传递,该方案前端可随意篡改数据,安全性极低。
  • 生产环境建议把session存储到Redis、MongoDB等持久化存储中,默认的内存存储不适合生产环境,会有内存泄漏、服务重启数据丢失的问题。
  • OTP的过期时间一定要设置,避免长期有效带来的安全风险。

内容的提问来源于stack exchange,提问作者Ryan143

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 21:06:01