Express+React令牌认证:应用中req.cookies为空但Postman正常
我用React做前端、Express做后端搭建Web应用,尝试基于Cookie实现令牌认证。该配置在Postman中运行完全正常,但在React应用中测试时,后端的req.cookies始终为空对象。
现有代码片段
后端Cookie设置代码
const token = await user.generateToken(); res.status(200) .cookie("access_token", token, { httpOnly: true, secure: false, sameSite: "none", }).json({ message: "Token set", data });
后端令牌验证中间件
export const verifyToken = (req, res, next) => { const token = req.cookies.access_token; console.log(req.cookies); // 浏览器中日志为空,Postman中正常 if (!token) return res.status(401).json({ message: "Access denied" }); jwt.verify(token, process.env.SECRET, (err, user) => { if (err) return res.status(403).json({ message: "Invalid token" }); req.user = user; next(); }); };
前端Axios请求代码
const apiCall = await axios.post( "http://localhost:3000/event/create", data, { withCredentials: true, credentials: "include", headers: { "Access-Control-Allow-Credentials": true, // 此头部无需设置可移除 }, } );
后端Express中间件配置
const express = require('express'); const cors = require('cors'); const cookieParser = require('cookie-parser'); const jwt = require('jsonwebtoken'); const app = express(); app.use(cookieParser()); app.use(express.json()); app.use(cors({ origin: "http://localhost:5173", credentials: true, }));
问题解决步骤
1. 修复Cookie的SameSite与Secure配置
浏览器安全策略规定:当Cookie设置sameSite: "none"时,必须同时开启secure: true(仅HTTPS环境生效)。本地开发使用HTTP协议时,这样的配置会导致浏览器拒绝存储Cookie,进而后端req.cookies为空。
修改为环境适配的配置:
const token = await user.generateToken(); const isProduction = process.env.NODE_ENV === 'production'; res.status(200) .cookie("access_token", token, { httpOnly: true, secure: isProduction, // 生产环境HTTPS下为true,本地HTTP为false sameSite: isProduction ? "none" : "lax", // 生产环境用none,本地用lax }).json({ message: "Token set", data });
2. 简化前端Axios请求配置
- 移除前端请求中多余的
Access-Control-Allow-Credentials头(该头是后端返回的响应头,前端无需设置) withCredentials与credentials只需保留一个,Axios中withCredentials: true已足够让浏览器携带Cookie
修改后的请求代码:
const apiCall = await axios.post( "http://localhost:3000/event/create", data, { withCredentials: true, } );
3. 确认CORS配置无冲突
确保后端CORS的origin严格匹配前端地址(如本地的http://localhost:5173),且credentials: true已正确开启(当前配置符合要求),同时避免多个CORS中间件导致的冲突。
内容的提问来源于stack exchange,提问作者ANUP KUMAR
相关产品推荐
相关产品推荐

