NestJS跨域设置Cookie Next.js服务端获取为空如何解决
问题根因
拿不到Cookie的核心原因有两点:
- 前后端端口不同属于跨源场景,NestJS设置Cookie时未配置跨域适配属性,浏览器默认会拦截第三方Cookie,根本不会把
cookie-data存储到localhost:3000域下 - Next.js默认不会自动解析请求头中的Cookie到
req.cookies字段,直接读取会得到空对象;且服务端发起接口请求时不会自动携带用户侧的Cookie,会导致校验失败
修复步骤
第一步:修改NestJS跨域与Cookie配置,确保Cookie能被浏览器正确存储
首先给Nest开启CORS,允许前端源携带凭证:
// NestJS main.ts 配置 async function bootstrap() { const app = await NestFactory.create(AppModule); app.enableCors({ origin: 'http://localhost:3000', // 精准匹配前端源,禁止填* credentials: true, // 核心配置:允许跨域请求携带Cookie }); await app.listen(3006); }
然后调整Cookie设置参数,补全跨场景必填属性:
// 登录/注册接口中设置Cookie的逻辑 context.res.cookie('cookie-data', { accessToken: token.accessToken, refreshToken: token.refreshToken, user: user, }, { domain: 'localhost', // 主域对齐,同域不同端口可共享Cookie httpOnly: true, // 鉴权场景优先设为true,禁止前端JS读取Cookie防XSS,此时客户端侧Cookies.get()拿不到值,所有鉴权逻辑放服务端处理即可;如果需要客户端读Cookie再设为false secure: process.env.NODE_ENV === 'production', // 本地HTTP环境设为false,生产HTTPS环境设为true sameSite: 'lax', // 跨源场景不要设strict,lax适配绝大多数业务场景 maxAge: 7 * 24 * 60 * 60 * 1000, // 按实际token有效期配置 path: '/' // 全站路径可访问 });
第二步:调整Next.js侧Cookie解析逻辑,兼容服务端场景
不要直接依赖req.cookies取值,手动从请求头解析Cookie,先安装解析依赖:npm i cookie @types/cookie -D
然后修改_app.tsx的getInitialProps逻辑:
import cookie from 'cookie'; import Cookies from 'js-cookie'; MyApp.getInitialProps = async (appContext) => { const appProps = await App.getInitialProps(appContext); let cookies = {}; if (!process.browser) { // 服务端从请求头手动解析Cookie const cookieHeader = appContext.ctx.req?.headers.cookie; cookies = cookieHeader ? cookie.parse(cookieHeader) : {}; } else { // 客户端从js-cookie读取 cookies = Cookies.get(); } return { ...appProps, cookies } }
第三步:配置请求携带凭证,服务端透传Cookie做校验
所有前端侧调用Nest接口的请求必须开启凭证携带配置:
- Axios全局配置
import axios from 'axios'; const request = axios.create({ baseURL: 'http://localhost:3006', withCredentials: true, // 跨域请求自动携带Cookie });
- 原生fetch配置
fetch('http://localhost:3006/auth/verify', { credentials: 'include', // 等价于withCredentials配置 })
服务端(getInitialProps逻辑内)调用Nest校验接口时,需要手动把用户访问前端时带的Cookie透传给后端,服务端请求不会自动携带浏览器上下文的Cookie:
// getInitialProps中私有路由校验逻辑示例 if (!process.browser) { const cookieHeader = appContext.ctx.req?.headers.cookie; // 校验Cookie有效性 const verifyRes = await fetch('http://localhost:3006/auth/verify', { headers: { cookie: cookieHeader || '' } }); // 校验不通过直接重定向到登录页 if (!verifyRes.ok) { appContext.ctx.res.writeHead(302, { Location: '/login' }); appContext.ctx.res.end(); return { ...appProps, cookies: {} }; } }
结果校验
配置完成后清空浏览器现有缓存Cookie,重新走登录流程:
- 打开浏览器DevTools -> Application -> Cookies -> http://localhost:3000,确认存在
cookie-data记录 - 刷新私有路由页面,服务端打印解析到的cookies可正常拿到令牌、用户信息
- 校验接口正常返回用户身份信息,不会异常跳转登录页
内容的提问来源于stack exchange,提问作者Serenity
相关产品推荐
相关产品推荐

