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

如何在Next.js的getServerSideProps中获取Firebase认证生成的跨端口会话Cookie?

解决Next.js跨端口Express后端Cookie无法获取的问题

你遇到的核心问题确实是同源策略限制——localhost的不同端口(比如Next.js用3000,Express用3001)会被浏览器判定为不同的源,所以后端设置的Cookie不会被绑定到Next.js的域名下,自然在getServerSideProps里拿不到。下面是两种靠谱的解决方案,按场景选择:

方案一:通过反向代理让请求同源(推荐开发+生产通用)

这是最稳妥的方式,让Next.js作为代理转发API请求到Express,这样前后端请求都处于同一个源下,Cookie就能正常共享。

1. 配置Next.js的反向代理

修改项目根目录的next.config.js,添加rewrites规则,把你的API请求转发到Express端口:

module.exports = {
  async rewrites() {
    return [
      {
        source: '/api/:path*', // 匹配Next.js下所有/api开头的请求
        destination: 'http://localhost:3001/api/:path*', // 替换成你的Express实际端口
      },
    ];
  },
};

2. 调整前端请求路径

之前你可能直接请求http://localhost:3001/api/xxx,现在改成请求/api/xxx,比如用fetch的话:

// 修改后
fetch('/api/auth/create-session', {
  method: 'POST',
  credentials: 'include', // 必须加上,确保Cookie被携带和保存
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ token: userToken }),
});

3. 后端Cookie配置简化

因为现在是同源请求,Cookie配置可以更简单,无需额外跨域相关设置:

const cookieOptions = { 
  maxAge: 60 * 60 * 24 * 5 * 1000,
  httpOnly: true, // 安全起见保持httpOnly
  secure: process.env.NODE_ENV === 'production', // 生产环境用HTTPS时设为true
  path: '/',
};
res.cookie('session', cookie, cookieOptions);

这样设置后,Next.js的getServerSideProps里用nookies.get(context)就能正常拿到session Cookie了。

方案二:配置跨域Cookie(适合前后端必须分离部署的场景)

如果必须保持前后端不同端口/域名,需要调整后端Cookie的跨域配置,同时前端请求带上凭证:

1. 修改Express的Cookie配置

需要添加sameSite和domain(针对生产环境),同时适配开发/生产环境的secure设置:

const cookieOptions = { 
  maxAge: 60 * 60 * 24 * 5 * 1000,
  httpOnly: true,
  secure: process.env.NODE_ENV === 'production', // 开发环境HTTP下必须设为false,否则Cookie不会被保存
  sameSite: process.env.NODE_ENV === 'production' ? 'none' : 'lax', // 生产跨域用none,开发可以lax
  path: '/',
  domain: process.env.NODE_ENV === 'production' ? '.yourdomain.com' : 'localhost', // 生产设置主域名,开发用localhost
};
res.cookie('session', cookie, cookieOptions);

2. 后端开启CORS并允许凭证

你的Express需要配置CORS中间件,允许Next.js的源并接受凭证:

const cors = require('cors');
app.use(cors({
  origin: process.env.NODE_ENV === 'production' ? 'https://your-next-app-domain.com' : 'http://localhost:3000',
  credentials: true, // 必须开启,允许携带Cookie
}));

3. 前端请求带上credentials: 'include'

和方案一一样,前端请求时必须加上这个选项,否则浏览器不会保存跨域Cookie:

fetch('http://localhost:3001/api/auth/create-session', {
  method: 'POST',
  credentials: 'include',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ token: userToken }),
});

注意:开发环境下如果用HTTP,secure: true会导致浏览器拒绝保存Cookie,所以一定要根据环境变量动态设置。

验证方法

你可以在浏览器的开发者工具里打开Application > Cookies,查看localhost下是否存在session Cookie。如果存在,说明配置生效,getServerSideProps就能拿到了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 07:53:14