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

EC2上Next.js中间件无法获取Express设置的Http-only Cookie问题

问题背景

在AWS EC2上部署了两个服务:

  • 基于Next.js 13的前端服务,域名:https://www.example.com
  • 基于Express的后端服务,域名:https://api.example.com

后端设置Http-only Cookie的代码:

response.cookie("refreshToken", refreshToken, {
      maxAge: 3.154e10, // 1 year
      httpOnly: true,
      secure: true,
      sameSite: 'none',
       domain: process.env.CLIENT_SERVER, // Set to your domain
       path: '/' // Accessible to all paths
    });

前端在middleware.ts中获取Cookie的代码:

function parseCookies(cookieHeader: any) {
  const cookies: any = {};
  if (cookieHeader) {
    const items = cookieHeader.split(";");
    items.forEach((item: string) => {
      const [key, value] = item.split("=");
      cookies[key.trim()] = value.trim();
    });
  }
  return cookies;
}

export async function middleware(request: NextRequest) {
  try {
    const cookieHeader = request.headers.get("cookie") || "";
    const cookies = parseCookies(cookieHeader);

    const accessToken = cookies["accessToken"];
    const refreshToken = cookies["refreshToken"];

问题现象:本地运行前端访问EC2后端API时,Cookie可正常获取;但前后端均部署在EC2上时,前端获取的Cookie为undefined。


排查与解决方案

1. 修正Cookie的domain配置

后端设置的domain参数必须为父域名,才能让www.example.com和api.example.com两个子域共享Cookie。当前如果process.env.CLIENT_SERVER的值是www.example.com,会导致只有www子域能识别Cookie,api子域设置的Cookie无法被前端读取。

修改后端代码的domain配置:

domain: ".example.com", // 确保环境变量的值为带前缀点的父域名

2. 确保前端请求开启withCredentials

跨子域请求时,前端必须显式配置携带凭证,否则浏览器不会传递Cookie。无论是用fetch还是Axios,都要开启对应选项:

  • fetch示例:
fetch('https://api.example.com/auth/login', {
  method: 'POST',
  credentials: 'include',
  // 其他请求配置
});
  • Axios示例:
axios.post('https://api.example.com/auth/login', requestData, {
  withCredentials: true
});

3. 验证HTTPS配置完整性

Cookie的secure: true要求请求必须通过HTTPS传输,需确认:

  • 前后端域名都配置了有效SSL证书(可通过AWS Certificate Manager配合ALB/CloudFront实现)
  • 前端HTTPS页面没有调用HTTP协议的后端接口(避免混合内容导致Cookie被拒绝)
  • EC2服务或前端代理(如Nginx)正确处理HTTPS流量,没有降级为HTTP

4. 排查Next.js Middleware的请求上下文

在Middleware中添加日志,确认cookie头是否被正确传递:

export async function middleware(request: NextRequest) {
  try {
    console.log("Received cookie header:", request.headers.get("cookie"));
    const cookieHeader = request.headers.get("cookie") || "";
    const cookies = parseCookies(cookieHeader);
    // 后续逻辑
  } catch (err) {
    console.error("Middleware error:", err);
  }
}

如果日志中没有refreshToken,说明Cookie未被浏览器携带,回到前三点重新排查;如果Cookie存在但解析失败,检查parseCookies函数的分割逻辑是否有问题(比如Cookie值包含=符号的情况)。

5. 检查浏览器Cookie存储

打开浏览器开发者工具(Application -> Cookies -> https://www.example.com),查看是否存在refreshToken:

  • 若不存在:重点检查后端Cookie的domain、secure、sameSite参数配置
  • 若存在但Middleware无法读取:确认Next.js配置中未限制Cookie传递,可在next.config.js中添加跨域凭证允许:
// next.config.js
module.exports = {
  async headers() {
    return [
      {
        source: '/(.*)',
        headers: [
          { key: 'Access-Control-Allow-Credentials', value: 'true' },
          { key: 'Access-Control-Allow-Origin', value: 'https://www.example.com' },
        ],
      },
    ];
  },
};

内容的提问来源于stack exchange,提问作者Naveed Ali Rehmani

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 13:20:25