Express.js中res.setHeader设置Authorization头重定向后失效问题
问题根源与解决方案
你遇到的问题本质是重定向机制导致的:
- 用
res.setHeader给响应设置的Authorization头是返回给浏览器的响应头,浏览器收到后不会自动把这个头带到下一个重定向的GET请求里 - 修改
req.headers.authorization仅在当前登录请求的上下文有效,重定向后的/NodeBooks/API/books请求是浏览器发起的全新请求,对应全新的req对象,自然没有之前设置的头信息
正确解决方案:用Cookie存储Token(服务端渲染场景首选)
服务端渲染场景下,登录后把JWT Token存在HttpOnly Cookie里是最安全且便捷的方式,浏览器会自动在后续请求中携带Cookie,无需手动处理请求头。
步骤1:安装并配置cookie-parser中间件
先安装依赖:
npm install cookie-parser
在Express入口文件中引入并使用:
import cookieParser from 'cookie-parser'; app.use(cookieParser());
步骤2:修改登录验证中间件
把原来设置响应头的逻辑改成设置Cookie:
export const validateLoginFromApi = async(req, res, next) => { const templates = path.join(process.cwd(), "src/public/templates"); const credentials = { username: req.body.username, password: req.body.password }; if(credentials.username === secret.username && credentials.password === secret.password){ jwt.sign({credentials}, 'secretkey', (err, token) => { // 用HttpOnly Cookie存储Token,防止XSS攻击窃取 res.cookie('authToken', token, { httpOnly: true, secure: process.env.NODE_ENV === 'production', // 生产环境开启(需HTTPS) maxAge: 24 * 60 * 60 * 1000, // Token有效期1天 path: '/' // 所有路径都携带该Cookie }); res.redirect("/NodeBooks/API/books"); }); }else{ res.status(403).sendFile("403.html", {root: templates}); } }
步骤3:修改JWT验证中间件
从Cookie中读取Token进行验证,同时修复原代码中next()位置错误的问题(原代码不管验证成功与否都会执行next(),存在安全隐患):
export function verifyWebToken(req, res, next) { const token = req.cookies.authToken; if (!token) { return res.status(403).sendFile('403.html', {root: templates}); } jwt.verify(token, "secretkey", (err) => { if (err) { return res.status(403).sendFile('403.html', {root: templates}); } // 验证通过后才调用next,进入下一个中间件 next(); }); }
其他可选方案(不推荐服务端渲染场景)
- 前端主动携带头:如果是单页应用,登录成功后返回Token给前端,前端存储Token后主动发起带
Authorization: Bearer xxx头的请求到目标接口,这种情况下不要用重定向 - URL参数携带Token:重定向时把Token作为查询参数(如
/NodeBooks/API/books?token=xxx),但URL会暴露Token,存在安全风险,仅临时调试用
内容的提问来源于stack exchange,提问作者Toms_Hd3z
相关产品推荐
相关产品推荐

