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

Express.js中JWT认证中间件出现Cannot set headers重复响应错误

解决JWT认证中间件的“Cannot set headers after they are sent to the client”错误

问题原因

你的代码存在两处核心问题,导致重复发送HTTP响应:

  1. 异步回调与外层响应冲突:jwt.verify是异步方法,回调函数还未执行时,外层的return res.json(...)已经触发,同一请求会发送两次响应。
  2. 中间件越权发送响应:验证成功后,你先调用res.json({ data: token_decode })发送响应,随后又调用next()让请求进入后续路由,后续路由若再发送响应就会触发“重复设置响应头”错误。中间件的职责是验证权限并传递上下文,而非直接返回业务响应。

修复后的代码

const jwt = require("jsonwebtoken");
const checkUserAuthentication = (req, res, next) => {
  const token = req.headers.token;
  
  // 无token直接返回错误
  if (!token) {
    return res.json({
      status: 0,
      msg: "Authorization failed: No token provided"
    });
  }

  try {
    // 使用同步验证替代异步回调,避免执行顺序问题
    const token_decode = jwt.verify(token.toString(), "secret");
    // 将解码后的用户信息挂载到req对象,供后续路由使用
    req.authUser = token_decode;
    // 放行请求到下一个中间件/路由
    next();
  } catch (err) {
    // 验证失败返回错误
    return res.json({
      status: 0,
      err: err.message,
      msg: "Authorization failed: Invalid token"
    });
  }
};

module.exports = checkUserAuthentication;

关键修改点

  • 提前判断无token场景:直接返回错误并终止函数,避免进入后续逻辑。
  • 改用同步验证逻辑:用try/catch捕获验证错误,代码逻辑更线性,避免异步回调导致的响应冲突。
  • 移除中间件内的业务响应:仅在验证失败时返回错误,验证成功后将用户信息挂载到req,由后续路由处理响应。
  • 确保单一出口:每个分支要么返回响应,要么调用next(),避免重复发送响应。

内容的提问来源于stack exchange,提问作者Swapnil Mane

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 09:45:35