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

MERN应用中前端调用验证接口时JWT Token返回undefined问题

问题:MERN应用中JWT前端验证返回Token undefined的排查

我在MERN应用中使用JWT Token进行身份验证,通过Postman调用登录接口http://127.0.0.1:1000/api/v1/users/login登录用户后,再调用验证接口http://127.0.0.1:1000/api/v1/users/verify时Token可正常返回。但在React前端执行相同操作时,Token返回undefined(Token存储在Cookie中)。以下是我的React代码和Express端的Token验证代码,请问问题出在哪里?

React代码

function Welcome() {
  const [user, setUser] = useState("");
  const sendRequest = async () => {
    const res = await axios
      .get("http://127.0.0.1:1000/api/v1/users/verify", {
        withCredentials: true,
      })
      .catch((err) => console.log(err));

    const data = await res.data;
    console.log("RESPONSE", data);
    return data;
  };
  React.useEffect(() => {
    sendRequest().then((data) => console.log(data));
  }, []);
  console.log(user);
  return <div>Welcome</div>;
}

Express端验证Token代码

exports.verifyToken = async (req, res, next) => {
  const cookies = await req.headers.cookie;
 
  const token = cookies.split("=")[1];


  if (!token) {
    res.status(404).json({ message: "no token found" });
  }

  jwt.verify(String(token), process.env.JWT_SECRET, (err, user) => {
    if (err) {
      return res.status(400).json({message: "Invalid token" });
    }

    req.id = user.id;
  });
  next();
};

问题分析与解决方案

1. Express端核心问题

  • await req.headers.cookie无意义且出错:req.headers.cookie是同步属性,不是Promise,加await会导致cookies变为undefined,后续split操作直接报错。
  • 未处理cookies不存在的情况:如果浏览器没传Cookie,cookies.split会抛出Cannot read property 'split' of undefined错误,直接导致请求失败。
  • 错误响应后未终止流程:if (!token)返回响应后,代码仍会执行next(),导致后续逻辑混乱。
  • 异步回调导致next()提前执行:jwt.verify是异步回调,next()会在验证完成前执行,后续路由无法获取req.id。

2. 修正后的Express验证代码

exports.verifyToken = async (req, res, next) => {
  const cookies = req.headers.cookie; // 移除不必要的await

  // 先判断Cookie是否存在
  if (!cookies) {
    return res.status(404).json({ message: "no token found" });
  }

  const token = cookies.split("=")[1];
  if (!token) {
    return res.status(404).json({ message: "no token found" });
  }

  try {
    // 使用Promise版本的jwt.verify,确保验证完成后再执行next
    const user = await jwt.verify(String(token), process.env.JWT_SECRET);
    req.id = user.id;
    next();
  } catch (err) {
    return res.status(400).json({ message: "Invalid token" });
  }
};

3. 额外必要配置

  • CORS跨域配置:后端必须允许前端跨域携带凭证,否则浏览器不会发送Cookie:
const cors = require('cors');
app.use(cors({
  origin: "http://localhost:3000", // 替换为你的前端实际地址
  credentials: true
}));
  • 登录接口Cookie设置:设置Cookie时需配置正确的属性,确保浏览器能正常存储并携带:
// 登录成功后设置Cookie的示例
res.cookie("token", generatedToken, {
  httpOnly: true, // 防止XSS攻击
  secure: process.env.NODE_ENV === "production", // 生产环境开启(需HTTPS)
  sameSite: "Lax", // 适配跨域场景,若完全跨域可设为"None"并配合secure
  maxAge: 24 * 60 * 60 * 1000 // Cookie有效期1天
});

4. React端检查点

  • 确保登录请求也设置了withCredentials: true,否则浏览器不会保存登录接口返回的Cookie:
// 登录请求示例
await axios.post("http://127.0.0.1:1000/api/v1/users/login", loginData, {
  withCredentials: true
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 03:45:49