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

前端跨域请求未携带Authorization头与Cookie的JWT认证问题

问题:前端跨域请求无法携带HttpOnly Cookie,后端收不到Authorization/Cookie头

我在为已认证用户保护页面时,遇到后端无法接收Cookie和Authorization头的问题。

最初我手动在请求头里添加Authorization:

headers: {
  Authorization: `Bearer ${TOKEN}`
}

但为了提升安全性,后端设置Cookie时启用了httpOnly: true,导致前端无法直接获取token。于是我在CORS和Axios中都配置了credentials: true,期望请求能自动携带Cookie。

现有配置

后端CORS配置:

const corsConfig = {
  origin: [process.env.BASE_URL],
  credentials: true,
  allowedHeaders: ["Content-Type"],
}

前端Axios配置:

const api = axios.create({
  withCredentials: true,
  baseURL: BASE_URL
})

Cookie JWT认证中间件:

const cookieJwtAuth = async (req, res, next) => {
  try {
    console.log(req.headers);
    const [, token] = req.headers.authorization.split(" ");
    
    if (!token) {
      return res.status(401).json({
        statusCode: 401,
        message: "Token not found",
      });
    }
    const decodedToken = await jwt.verify(token, process.env.SECRET);

    if (!decodedToken.username) {
      return res.status(401).json({
        statusCode: 401,
        message: "Username not found in token",
      });
    }

    req.user = decodedToken;
    next();

  } catch (err) {
    res.clearCookie("auth");
    return res.status(400).json({
      statusCode: 400,
      message: "Not authorized",
    })
  }
}

问题现象

通过console.log(req.headers)对比前端和Insomnia的请求头,发现明显差异:

  • 前端请求头中无cookie和authorization字段
  • Insomnia请求头正常携带这两个字段,接口测试完全正常

我尝试修改CORS和Axios配置,甚至在CORS的allowedHeaders中添加了"Authentication",但问题依旧。当前核心错误是前端请求的req.headers.authorization为undefined,导致调用split方法时直接报错。


解决方案

1. 修正CORS配置的核心问题

首先确认前端请求的origin(http://127.0.0.1:5500)和后端CORS配置的process.env.BASE_URL完全一致,包括协议、域名、端口(localhost和127.0.0.1在跨域规则中属于不同 origin)。

同时修正CORS配置的字段错误,补充必要的头信息:

const corsConfig = {
  origin: [process.env.BASE_URL], // 确认值与前端origin完全匹配
  credentials: true,
  allowedHeaders: ["Content-Type", "Authorization"], // 修正拼写错误,添加Authorization
  exposedHeaders: ["Set-Cookie"], // 允许前端读取Set-Cookie响应头
}

2. 重构中间件逻辑:从Cookie而非Authorization头取token

因为Cookie设置了httpOnly: true,前端无法将token放到Authorization头中,正确做法是直接从req.cookies读取后端设置的auth Cookie(参考Insomnia请求中的auth=xxx):

const cookieJwtAuth = async (req, res, next) => {
  try {
    console.log(req.cookies); // 打印Cookie确认是否能正常获取
    const token = req.cookies.auth; // 从Cookie中读取token
    
    if (!token) {
      return res.status(401).json({
        statusCode: 401,
        message: "Token not found in cookie",
      });
    }
    const decodedToken = await jwt.verify(token, process.env.SECRET);

    if (!decodedToken.username) {
      return res.status(401).json({
        statusCode: 401,
        message: "Username not found in token",
      });
    }

    req.user = decodedToken;
    next();

  } catch (err) {
    res.clearCookie("auth");
    return res.status(400).json({
      statusCode: 400,
      message: "Not authorized",
    })
  }
}

注意:必须确保后端已安装并启用cookie-parser中间件,否则req.cookies会是undefined:

const cookieParser = require('cookie-parser');
app.use(cookieParser());

3. 确认后端Cookie设置的正确性

后端设置Cookie时,需匹配跨域场景调整参数:

res.cookie('auth', token, {
  httpOnly: true,
  secure: process.env.NODE_ENV === 'production', // 生产环境启用secure(仅HTTPS)
  sameSite: process.env.NODE_ENV === 'production' ? 'none' : 'lax', // 跨域场景需设为none(配合secure)
  maxAge: 24 * 60 * 60 * 1000, // 1天有效期
  path: '/' // 确保所有路由都能携带该Cookie
});

4. 前端Axios配置校验

确认Axios的withCredentials: true未被请求级配置覆盖,且baseURL与后端服务地址完全一致,避免因地址不匹配导致Cookie无法携带。


内容的提问来源于stack exchange,提问作者Eric Zardo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 19:25:52