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

使用Mongoose.findOne()无法找到用户的问题排查求助

问题

我通过fetch()调用接口实现登录功能,前端提交按钮触发handleSubmit函数,代码如下:

const context = useContext(AuthContext);
const navigate = useNavigate();

const handleSubmit = (event) => {
  event.preventDefault();
  const data = new FormData(event.currentTarget);
  if (data) {
    fetch("http://localhost:4000/api/user/login", {
      method: "POST",
      crossDomain: true,
      headers: {
        "Content-Type": "application/json",
        "Accept": "application/json",
        "Access-Control-Allow-Origin": "http://localhost:4000",
      },
      body: JSON.stringify({
        email: data.get("email"),
        password: data.get("password"),
      }),
    })
      .then((res) => res.json())
      .then((result) => {
        console.log(result);
        if (result.token) {
          context.login(result);
          navigate("/Home");
        }
      })
      .catch((e) => console.log(e));
  } else {
    console.log("Login failed.");
  }
};

后端登录控制器代码:

const login = async (req, res, next) => {
  function generateToken(user) {
    return jwt.sign(
      {
        id: user.id,
        email: user.email,
        username: user.username,
      },
      SECRET_KEY,
      { expiresIn: "1h" }
    );
  }

  const user = await User.findOne({ email });
  if (!user) {
    console.log("User not found.");
  }

  const match = bcrypt.compare(password, user.password);
  if (!match) {
    console.log("Wrong password.");
  }

  const token = generateToken(user);

  return { token };
};

目前控制台抛出“User not found”错误,但该邮箱对应的用户已存在于MongoDB Atlas数据库中,求排查指导。


排查指导

  • 修复后端参数获取逻辑
    后端代码中直接使用email和password变量,但未从请求体req.body中提取,这是核心问题。必须在函数开头添加:

    const { email, password } = req.body;
    

    否则email变量为undefined,数据库查询自然找不到用户。

  • 统一邮箱大小写处理
    MongoDB查询默认大小写敏感,若数据库存储的是test@example.com,前端传入Test@example.com会导致查询失败。处理方式:

    1. 前端提交时转小写:data.get("email").toLowerCase()
    2. 后端查询时同步转小写:const user = await User.findOne({ email: email.toLowerCase() });
      建议注册阶段就将邮箱转小写存储,避免后续匹配问题。
  • 验证数据库查询准确性

    1. 在后端打印接收的邮箱值:console.log("Received email:", email);,确认与前端传入值一致
    2. 检查User模型的email字段定义,确保与数据库集合中的字段名完全匹配(无拼写错误,比如不要写成Email)
  • 修复异步逻辑与错误处理

    1. bcrypt.compare是异步函数,必须加await,否则match会是Promise对象,导致密码校验逻辑失效:
      const match = await bcrypt.compare(password, user.password);
      
    2. 添加try/catch捕获数据库查询异常,避免程序崩溃:
      try {
        const user = await User.findOne({ email: email.toLowerCase() });
        // 后续登录逻辑
      } catch (err) {
        console.error("Database query error:", err);
        return res.status(500).json({ message: "Server error" });
      }
      
    3. 未找到用户或密码不匹配时,给前端返回明确错误响应,而非仅打印日志:
      if (!user) {
        console.log("User not found.");
        return res.status(404).json({ message: "User not found" });
      }
      
  • 检查前端请求实际内容
    打开浏览器开发者工具「Network」标签,找到登录请求,查看「Payload」选项卡,确认email和password是否正确发送、格式是否为JSON。

  • 修正CORS配置
    前端请求中设置Access-Control-Allow-Origin无效,该字段是后端响应头。需在后端通过cors中间件配置跨域,确保请求参数能正常传递。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 22:55:17