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

用户登录接口返回错误userId问题求助(附相关代码)

问题排查与解决方案

问题根源

  1. 模型字段不匹配:后端通过email: req.body.email查询用户,但你的User Schema中未定义email字段(仅存在clubEmail),这会导致查询条件无法精准匹配目标用户,甚至返回数据库中第一个符合“无约束”条件的文档。
  2. 前后端密码字段名不一致:前端请求时传递的是passwordHash: password,但后端验证时读取的是req.body.password,这会使bcrypt.compareSync的第一个参数为undefined。若数据库中存在密码哈希为空的用户,会意外通过验证并返回该用户。

修复步骤

1. 修正User模型(添加/调整登录标识字段)

如果登录使用的是用户个人邮箱,在Schema中添加email字段并设置唯一性约束:

const userSchema = mongoose.Schema({
    email: {
        type: String,
        required: true,
        unique: true, // 确保邮箱唯一,避免重复匹配
        minlength: 5,
        maxlength: 100
    },
    contactName: {
        type: String,
        required: true,
        minlength: 5,
        maxlength: 50
    },
    phone: {
        type: String,
        required: true,
        minlength: 5,
        maxlength: 50
    },
    passwordHash: {
        type: String,
        required: true,
        minlength: 5,
        maxlength: 1024
    },
    token: {
        type: String,
    },
    isAdmin: {
        type: Boolean,
        default: false
    },
    clubName: {
        type: String,
        required: true,
    },
    clubAddress: {
        type: String,
        required: true,
    },
    clubEmail: {
        type: String,
        required: true,
    },
    clubPhone: {
        type: String,
        required: true,
    },
    clubWebsite: {
        type: String,
        required: true,
    },
    clubContact: {
        type: String,
        required: true,
    },
})

若登录使用的是clubEmail,则将后端查询条件改为clubEmail: req.body.email,无需新增字段。

2. 修正前端请求的密码字段名

前端请求时传递password而非passwordHash,与后端接收字段保持一致:

const handleSubmit = () => {
    axios
      .post(`${baseURL}users/login`, {
        email: email,
        password: password, // 修正字段名
      })
      .then(res => {
        console.log('USER ID TOKEN', res.data.token);
        setbearerToken(res.data.token);
        AsyncStorage.setItem('bearerToken', res.data.token);
        const decoded = decode(res.data.token);
        setTokenID(decoded.userId);
        dispatch(setUser(res.data));
      });
};

3. 添加日志辅助排查

在后端登录路由中添加日志,确认请求参数与查询结果:

router.post("/login", async (req, res) => {
  console.log("Login request email:", req.body.email);
  const user = await User.findOne({
    email: req.body.email,
  });
  console.log("Queried user:", user);
  
  const secret = process.env.SECRET;
  if (!user) {
    return res.status(400).send("the user not found!");
  }
  if (user && bcrypt.compareSync(req.body.password, user.passwordHash)) {
    const token = jwt.sign(
      {
        userId: user.id,
        isAdmin: user.isAdmin,
      },
      secret,
      { expiresIn: "1d" }
    );
    res.status(200).send({ user: user.email, token: token });
  } else {
    res.status(400).send("password is wrong!");
  }
});

4. 确保登录字段唯一性

在数据库中给登录标识字段(如email或clubEmail)创建唯一索引,避免多个用户使用同一标识导致查询错误。

内容的提问来源于stack exchange,提问作者Jason Byron Beedle

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 04:00:46