Nest.js无法设置Cookie问题排查及解决咨询
问题描述
我开发了/sign-in接口,原本返回包含access token和refresh token的对象。后来调整接口逻辑:将access token以JSON格式返回,同时尝试把refresh token存入Cookie,但前端无法获取到该Cookie(已在axios中配置withCredentials: true),但Postman请求能正常拿到Cookie。另外,无论前端还是Postman请求,服务器终端都会抛出如下错误:
Error [ERR_INTERNAL_ASSERTION]: This is caused by either a bug in Node.js or incorrect usage of Node.js internals.
Please open an issue with this stack trace at https://github.com/nodejs/node/issuesat assert (internal/assert.js:14:11) at ServerResponse.detachSocket (_http_server.js:223:3) at resOnFinish (_http_server.js:685:7) at ServerResponse.emit (events.js:314:20) at onFinish (_http_outgoing.js:735:10) at onCorkedFinish (_stream_writable.js:673:5) at afterWrite (_stream_writable.js:490:5) at afterWriteTick (_stream_writable.js:477:10) at processTicksAndRejections (internal/process/task_queues.js:83:21)
请问问题根源是什么,如何解决才能让前端正常获取Cookie?
问题原因
- Cookie跨域属性配置不全:浏览器遵循同源策略,Postman则不受此限制。如果Cookie未配置
SameSite、Domain等关键跨域属性,浏览器会拒绝保存Cookie,导致前端拿不到。 - 响应处理逻辑冲突:服务器抛出的
ERR_INTERNAL_ASSERTION错误,是Node.js内部断言失败导致的,通常因为响应处理中出现重复发送响应(比如多次调用res.json()/res.send())、或在响应结束后仍尝试修改响应对象,触发了Node.js内部的校验逻辑。
解决方法
一、完善Cookie跨域配置
设置Cookie时必须添加适配跨域场景的属性,以Express框架为例:
res.cookie('refreshToken', refreshToken, { httpOnly: true, // 禁止前端JS读取,提升refresh token安全性 secure: process.env.NODE_ENV === 'production', // 生产环境强制HTTPS传输 sameSite: process.env.NODE_ENV === 'production' ? 'none' : 'lax', // 跨域需设为none,配合secure domain: '.yourdomain.com', // 配置前后端共同的主域名(如前端app.yourdomain.com,后端api.yourdomain.com) path: '/', // 使Cookie在整个域名下生效 maxAge: 7 * 24 * 60 * 60 * 1000 // 设置过期时间,示例为7天 });
若为非跨域场景,sameSite可设为lax或strict,domain设为当前域名即可。
二、修复响应处理冲突问题
检查接口代码,确保响应逻辑唯一:
- 确保整个接口流程中只调用一次响应发送方法(
res.json()/res.send()/res.end()),避免重复发送响应。 - 排查异步逻辑分支,确保所有代码路径都只有一个响应出口,防止异步回调触发重复响应。
- 检查错误处理逻辑,避免在响应已发送后仍尝试修改响应对象。
错误示例(需避免):
// 错误:设置Cookie后重复发送响应 res.cookie('refreshToken', token); res.json({ accessToken: token }); // 后续代码又意外调用响应方法 res.json({ code: 200 }); // 触发内部断言错误
三、确认前端配置有效性
确保axios的withCredentials配置正确应用:
axios.post('/sign-in', loginParams, { withCredentials: true });
同时前端域名需与Cookie配置的domain属性匹配,否则浏览器会拒绝存储Cookie。
内容的提问来源于stack exchange,提问作者dokichan
相关产品推荐
相关产品推荐

