Node.js(非Express环境)无法从React客户端获取JWT Cookie
问题定位与修复方案
核心问题集中在客户端请求配置错误、后端未处理OPTIONS预请求、Cookie属性缺失这几个方面,以下是具体修复步骤:
1. 修正客户端axios请求配置
你把credentials: "include"错误放在了请求体参数里,它应该作为axios请求配置的顶级属性;同时Access-Control-Allow-Credentials是后端返回的响应头,客户端不需要设置,直接删除该请求头。
修改后的客户端代码:
import axios from "axios"; const authorizeUser = async () => { try { const result = await axios.post( "http://localhost:5000/authorize", {}, // 无请求体则留空,有参数则正常传入 { credentials: "include", // 移至配置对象的顶级属性 headers: { "Content-Type": "application/json", }, } ); return result; } catch (error) { console.log(error); } };
2. 后端处理OPTIONS预请求
浏览器发送带Cookie的跨域请求时,会先发送OPTIONS预请求验证权限,你的当前代码未处理该请求,导致预请求失败,后续请求不会携带Cookie。需要在服务器逻辑中添加OPTIONS请求的处理:
修改后端index.js的服务器逻辑:
const server = http.createServer((req, res) => { res.setHeader("Access-Control-Allow-Origin", "http://localhost:3000"); res.setHeader("Access-Control-Allow-Credentials", true); res.setHeader( "Access-Control-Allow-Methods", "GET, POST, OPTIONS, PUT, PATCH, DELETE" ); res.setHeader( "Access-Control-Allow-Headers", "Origin, X-Requested-With, X-PINGOTHER,Content-Type, Accept" ); // 处理OPTIONS预请求,直接返回200状态 if (req.method === "OPTIONS") { res.writeHead(200); res.end(); return; } // 登录接口 if (req.url === "/login" && req.method === "POST") { loginUser(req, res, "users"); } // 授权验证接口 else if (req.url === "/authorize" && req.method === "POST") { authorizeUser(req, res); } // 404路由 else { res.writeHead(404, {"Content-Type": "application/json"}); // 修正原contentType的格式错误 res.end(JSON.stringify({ message: "Route not found" })); } });
注:原代码中contentType变量格式错误,直接在writeHead中传入正确的响应头对象即可。
3. 完善Set-Cookie属性
你的Cookie缺少Path=/(确保全站路由都能携带)和SameSite(现代浏览器强制要求的属性,否则可能拒绝Cookie),建议加上HttpOnly提升安全性(防止XSS窃取Cookie):
修改loginUser函数的Set-Cookie头:
res.setHeader( "Set-Cookie", `token=${result.token}; Path=/; HttpOnly; SameSite=Lax; Secure=${process.env.NODE_ENV === 'production'}` );
Path=/:确保所有路由请求都会携带该CookieHttpOnly:禁止前端JS读取Cookie,避免XSS攻击SameSite=Lax:允许同站请求携带Cookie,跨站需用户交互(适合开发环境),生产环境若需跨站可设为SameSite=None,但必须配合SecureSecure:生产环境开启,仅HTTPS请求才会携带Cookie
验证修复
- 重启后端服务
- 重新登录,在浏览器
Application -> Cookies中确认Cookie已正确设置 - 调用
authorizeUser,此时请求头会自动携带Cookie: token=xxx,后端console.log(req.headers)可看到该字段
内容的提问来源于stack exchange,提问作者rs.wright
相关产品推荐
相关产品推荐

