NextJS生产环境getServerSideProps跨域无法传递Cookie问题求解
问题根因
你遇到的问题本质不是getServerSideProps读不到Cookie,是跨根域名场景下第三方Cookie被浏览器默认拦截,导致用户访问你Vercel前端域名时,Heroku后端种的HttpOnly JWT Cookie根本没被浏览器存储,自然context.req.headers.cookie里拿不到对应值。开发环境前后端同属localhost同站上下文,所以不会触发这个限制。
你不需要强制把后端配置为前端子域名,两种可行方案如下,按需选择即可:
方案1:保留跨域部署,修正配置(无需调整域名架构)
这个方案不需要改域名解析,只要修正前后端的Cookie、CORS配置即可:
- 后端CORS配置修正
Access-Control-Allow-Origin不能设置为通配符*,必须精确匹配你的Vercel前端生产域名,有预览环境的话额外加Vercel预览域名的匹配逻辑- 必须开启响应头
Access-Control-Allow-Credentials: true,否则浏览器不会允许跨域请求携带、存储Cookie
- Cookie属性修正
你存储JWT的HttpOnly Cookie,必须调整属性适配跨站场景:SameSite=None:允许跨站请求携带CookieSecure:必须和SameSite=None搭配开启,仅允许HTTPS请求下传输Cookie(Heroku默认支持HTTPS,生产环境直接用https开头的API地址即可)
本地开发环境可以保留SameSite=Lax,通过环境变量区分开发/生产配置即可
- 修正服务端请求代码
你现有代码里的withCredentials: true是浏览器端请求的配置,Node.js环境下运行的axios没有浏览器Cookie上下文,这个配置无效,删掉即可,直接透传客户端请求的Cookie头就行,修正后的代码:
export const getSession = async (context: GetServerSidePropsContext) => { try { const response = await axios.get( process.env.NEXT_PUBLIC_API_URL + "/auth/user", { headers: { // 直接透传客户端传来的原始Cookie头 Cookie: context.req.headers.cookie ?? "", }, } ); return response; } catch (error) { console.log(error); return null; } }; export const getServerSideProps: GetServerSideProps = async (context) => { const session = await getSession(context); if (!session) { return { redirect: { destination: "/login", permanent: false, }, props: {}, }; } return { props: { session: session.data }, }; };
方案2:配置后端为前端子域名(长期更稳定)
目前主流浏览器对第三方Cookie的限制持续收紧(Safari已经默认全量拦截第三方Cookie,Chrome也在推进全量封禁),如果想长期规避这类问题,优先选择子域名方案:
- 给前端根域名加一条CNAME记录,比如把
api.yourdomain.com解析到Heroku服务,在Heroku后台绑定这个自定义域名并配置好SSL证书 - 前后端同属
yourdomain.com根域名,属于第一方上下文,不需要设置SameSite=None,Cookie用默认的SameSite=Lax+HttpOnly+Secure即可,Cookie的domain属性设置为.yourdomain.com(前面带点,允许根域名和所有子域名共享Cookie) - 这种场景下CORS配置可以简化,甚至不需要跨域配置,安全性更高,也不会被未来的浏览器Cookie策略影响。
注意:如果Vercel侧配置了边缘缓存/CDN规则,记得对需要鉴权的动态路由跳过Cookie头缓存,避免缓存的响应里带了其他用户的Cookie信息。
内容的提问来源于stack exchange,提问作者Hashem Mashem
相关产品推荐
相关产品推荐

