设置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 })
最后,验证流程
- 用户登录,后端设置包含Token的Cookie
- 前端发起添加商品请求,
withCredentials: true确保Cookie被携带 - 后端的
verifySeller中间件读取Cookie中的Token,验证并获取卖家信息 addProduct直接用req.seller添加商品,不再依赖前端传userId
这样应该就能解决「User not found」的问题了,同时也让你的鉴权流程更安全可靠。
备注:内容来源于stack exchange,提问作者Lemuel Lacanlale

