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

设置withCredentials=true仍无法读取Cookie中的Token,添加商品时返回'User not found'错误求助

设置withCredentials=true仍无法读取Cookie中的Token,添加商品时返回'User not found'错误求助

看起来你遇到的核心问题是:前端已经设置了withCredentials: true,但后端还是无法通过Cookie中的Token识别用户,导致返回「User not found」错误。结合你提供的代码,我来帮你梳理可能的原因和解决方案:

首先,发现一个关键问题:你的后端逻辑依赖前端传userId,而非从Token解析用户身份

看你的addProduct函数,是直接从req.body里拿userId去查询卖家的——但正常的鉴权流程应该是:后端通过Cookie中的Token自动解析出当前登录用户,而不是让前端主动传递userId。这种做法不仅不安全(前端可以随意篡改userId),也说明你的后端根本没在验证Cookie里的Token,这大概率是错误的根源。

接下来,一步步解决问题:

1. 检查后端CORS配置是否允许携带凭证

如果你的前端和后端是跨域的,必须确保CORS配置正确,否则Cookie不会被携带到后端:

const cors = require('cors');
// 注意:origin不能设为*,必须是你的前端具体域名,比如http://localhost:3000
app.use(cors({
  origin: '你的前端域名',
  credentials: true, // 关键:允许携带Cookie等凭证
}));

2. 配置Cookie解析中间件

后端需要用cookie-parser来读取Cookie中的Token,先安装并配置:

const cookieParser = require('cookie-parser');
app.use(cookieParser());

3. 添加登录验证中间件,自动从Cookie提取Token并验证

你需要写一个中间件,在addProduct接口执行前,先验证Cookie里的Token,解析出用户身份并挂载到req对象上:

const jwt = require('jsonwebtoken');
const sellerModel = require('./你的sellerModel路径');

const verifySeller = async (req, res, next) => {
  try {
    // 假设你登录时把Token存在名为authToken的Cookie里
    const token = req.cookies.authToken;
    if (!token) {
      return res.json({ success: false, msg: 'User not found' });
    }
    // 验证Token并解析出用户ID
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    // 查询对应的卖家信息
    const seller = await sellerModel.findById(decoded.id);
    if (!seller) {
      return res.json({ success: false, msg: 'User not found' });
    }
    // 把卖家信息挂载到req上,后续接口直接用
    req.seller = seller;
    next(); // 继续执行后续的addProduct逻辑
  } catch (err) {
    res.json({ success: false, msg: 'Invalid or expired token' });
  }
};

然后在你的路由里使用这个中间件:

// 注意:要把verifySeller放在addProduct前面
router.post('/api/seller/add', verifySeller, addProduct);

4. 修改addProduct函数,不再依赖前端传userId

现在中间件已经把卖家信息挂载到req.seller了,你可以直接用它,不需要再从req.body拿userId查询:

export const addProduct = async (req, res) => {
  try {
    // 移除userId,从req.seller获取当前登录卖家
    const { name, description, price, category, subCategory, sizes, bestseller } = req.body;

    // ... 图片上传的逻辑保持不变

    const productData = {
      name,
      description,
      category,
      price: Number(price),
      subCategory,
      bestseller: bestseller === "true",
      sizes: JSON.parse(sizes),
      image: imagesUrl,
      date: Date.now(),
    };

    // 直接用req.seller,不需要再查询一次
    const seller = req.seller;
    seller.products.push(productData);
    await seller.save();

    res.json({ success: true, msg: "Product Added" });
  } catch (err) {
    console.log(err);
    res.json({ success: false, msg: err.message });
  }
};  

5. 检查登录时Cookie的设置是否正确

当用户登录成功后,你设置Cookie时要注意以下属性,否则Cookie可能无法被跨域携带:

// 登录成功后设置Cookie的示例
res.cookie('authToken', 生成的Token, {
  httpOnly: true, // 防止XSS攻击,禁止前端JS读取Cookie
  secure: process.env.NODE_ENV === 'production', // 生产环境必须开启HTTPS才生效
  sameSite: 'None', // 跨域场景下必须设为None,同域可以设为Lax/Strict
  maxAge: 7 * 24 * 60 * 60 * 1000, // Cookie有效期7天
});

6. 前端去掉手动设置的Content-Type

你的前端axios请求里手动设置了"Content-Type": "multipart/form-data",这会导致请求头缺少boundary参数,反而会让后端无法正确解析FormData。建议去掉这个配置,axios会自动为FormData设置正确的请求头:

// 修改前
const response = await axios.post(backendUrl+'/api/seller/add',formData,{headers: {"Content-Type": "multipart/form-data"}, withCredentials:true})

// 修改后
const response = await axios.post(backendUrl+'/api/seller/add', formData, { withCredentials: true })

最后,验证流程

  1. 用户登录,后端设置包含Token的Cookie
  2. 前端发起添加商品请求,withCredentials: true确保Cookie被携带
  3. 后端的verifySeller中间件读取Cookie中的Token,验证并获取卖家信息
  4. addProduct直接用req.seller添加商品,不再依赖前端传userId

这样应该就能解决「User not found」的问题了,同时也让你的鉴权流程更安全可靠。

备注:内容来源于stack exchange,提问作者Lemuel Lacanlale

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.15 03:23:04