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

Node.js+MongoDB登录脚本无法匹配已注册用户数据求助

问题:登录功能无法正常生效

用Node.js编写了注册与登录脚本,将用户数据存储至MongoDB,预期已注册用户可通过注册邮箱登录,但当前登录功能无法正常生效。这是首次为React应用对接后端,以下是后端及React前端代码,请求排查修复:


后端代码

const User = require("./models/user");
const Worker = require("./models/worker");
app.post("/register", async (req, res) => {
    try {
      const { username, email, password } = req.body;

      // 检查邮箱是否已注册
      const existingUser = await User.findOne({ email });
      if (existingUser) {
        console.log("Email already registered:", email); // 调试日志
        return res.status(400).json({ message: "Email already registered" });
      }

      // 创建新用户
      const newUser = new User({ username, email, password });

      // 生成并存储验证令牌
      newUser.verificationToken = crypto.randomBytes(20).toString("hex");

      // 保存用户到数据库
      await newUser.save();

      // 调试日志验证数据
      console.log("New User Registered:", newUser);

      // 发送验证邮件
      // 使用你偏好的邮件服务或库发送邮件
      sendVerificationEmail(newUser.email, newUser.verificationToken);

      res.status(201).json({
        message:
          "Registration successful. Please check your email for verification.",
      });
    } catch (error) {
      console.log("Error during registration:", error); // 调试日志
      res.status(500).json({ message: "Registration failed" });
    }
  });

  const generateSecretKey = () => {
    const secretKey = crypto.randomBytes(32).toString("hex");

    return secretKey;
  };

  const secretKey = generateSecretKey();

  // 用户登录接口
  app.post("/login", async (req, res) => {
    try {
      const { email, password } = req.body;

      // 检查用户是否存在
      const user = await User.findOne({ email });
      if (!user) {
        return res.status(401).json({ message: "Invalid email or password" });
      }

      // 检查密码是否正确
      if (user.password !== password) {
        return res.status(401).json({ message: "Invalid password" });
      }

      // 生成token
      const token = jwt.sign({ userId: user._id }, secretKey);

      res.status(200).json({ token });
    } catch (error) {
      res.status(500).json({ message: "Login Failed" });
    }
  });

前端代码

const handleLogin = async ()  => {
    // 构造登录请求参数
    const user = {
      email: email,
      password: password,
    };

    try {
      const response = await fetch("http://10.0.2.2:3000/login", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify(user),
      });

      if (response.ok) {
        Alert.alert("Success Login");
        navigation.navigate("Home"); // 登录成功后跳转到首页
      } else {
        setButtonBgColor("#FF0000");
        Alert.alert("Login Error", "Invalid Email or Password");
      }
    } catch (error) {
      console.error(error);
      // 处理网络或其他错误
    }
  };

排查修复方案

1. 解决跨域问题

前端与后端域名/端口不同会触发跨域拦截,导致请求失败:

  • 安装cors依赖:npm install cors
  • 在后端代码开头引入并启用:
const cors = require('cors');
app.use(cors());

2. 修复密码存储与验证逻辑(核心功能+安全性)

当前明文存储密码,不仅不安全,还可能因编码/特殊字符导致比对失败,改用bcrypt加密:

  • 安装bcrypt:npm install bcrypt
  • 修改注册代码的密码处理:
const bcrypt = require('bcrypt');
// 注册逻辑中,创建用户前添加:
const saltRounds = 10;
const hashedPassword = await bcrypt.hash(password, saltRounds);
const newUser = new User({ username, email, password: hashedPassword });
  • 修改登录代码的密码比对:
// 替换原有的`if (user.password !== password)`
const isPasswordValid = await bcrypt.compare(password, user.password);
if (!isPasswordValid) {
  return res.status(401).json({ message: "Invalid password" });
}

3. 修复JWT密钥持久化问题

当前每次重启服务都会生成新的secretKey,导致之前的token失效,改用环境变量存储:

  • 安装dotenv:npm install dotenv
  • 创建.env文件,添加:SECRET_KEY=你的32位随机密钥(可使用之前generateSecretKey生成的字符串)
  • 在后端代码中引入:
require('dotenv').config();
const secretKey = process.env.SECRET_KEY;

4. 检查User模型定义

确保models/user.js中包含password字段,否则注册时不会存储密码:

const mongoose = require('mongoose');

const userSchema = new mongoose.Schema({
  username: { type: String, required: true },
  email: { type: String, required: true, unique: true },
  password: { type: String, required: true },
  verificationToken: String,
  isVerified: { type: Boolean, default: false } // 可选,用于邮箱验证逻辑
});

module.exports = mongoose.model('User', userSchema);

5. 前端调试优化

添加更详细的错误反馈,帮助定位问题:

catch (error) {
  console.error("登录请求异常详情:", error);
  Alert.alert("登录失败", "网络请求错误,请检查后端服务是否启动或配置正确");
}

同时打开调试工具的Network面板,查看请求的状态码和响应内容,精准定位问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 11:37:48