[英]Error: This is caused by either a bug in Node.js or incorrect usage of Node.js internals
我正在为我的服务创建身份验证机制。 在某个时刻,我遇到了 cookies 的问题。 更多你可以在这里找到,所以我解决了这个问题。
问题是我试图通过 2 个请求发送 cookie。 我的Next.js
前端向其内部 API 发送请求,然后,内部 API 才将此请求发送到后端。
这个问题的解决方案很简单,我要做的就是在后端设置 cookie 并在 headers 中返回它。 这是流程的外观。
这就是它的样子, Next.js
前端的端点。 除了响应中的数据,它接收 header,其中设置了 cookie(来自后端的响应)并在响应的 header 中发送,该响应将在前端发送,其中将设置 cookie:
import { NextApiRequest, NextApiResponse } from "next";
import { AxiosError } from "axios";
import { api } from "../../../api";
export default async (
req: NextApiRequest,
res: NextApiResponse
) => {
try {
const { data, headers } = await api.post('/user/sign-in', req.body)
if (headers["set-cookie"]) {
res.setHeader("Set-Cookie", headers["set-cookie"]);
}
return res.json(data)
} catch (error) {
return res
.status((error as AxiosError).response?.status as number)
.json((error as AxiosError).response?.data);
}
}
和后端端点:
import { Response as Res } from 'express';
import * as dayjs from 'dayjs';
...
async signIn(@Body() signInUserDto: SignInUserDto, @Response() res: Res) {
const { _at, _rt } = await this.userService.signIn(signInUserDto);
res.cookie('_rt', _rt, {
httpOnly: true,
expires: dayjs().add(7, 'days').toDate()
});
return res.send(_at);
}
这就是问题所在,因为express
的这个Response
class 我不断收到这个警告:
Error: 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/issues
at new NodeError (node:internal/errors:371:5)
at assert (node:internal/assert:14:11)
at ServerResponse.detachSocket (node:_http_server:249:3)
at resOnFinish (node:_http_server:819:7)
at ServerResponse.emit (node:events:390:28)
at onFinish (node:_http_outgoing:830:10)
at callback (node:internal/streams/writable:552:21)
at afterWrite (node:internal/streams/writable:497:5)
at afterWriteTick (node:internal/streams/writable:484:10)
at processTicksAndRejections (node:internal/process/task_queues:82:21)
这绝对是因为这个signIn
function 的样子,因为我试图像这样返回 - return this.userService.signIn(signInUserDto)
- 它有效,但在这种情况下我不能 cookie。
所以,我的问题是 - 这个错误是什么? 我可以忽略它吗? 如果没有,那我该如何解决?
提前致谢!
最后,我能够修复这个错误,首先,正如我所说,我经历了 2 个 API,从后端到前端 API,然后这个前端 API 才会将此请求发送到实际前端结尾。
所以,我所做的只是返回了 2 个令牌 - 刷新和访问 - 作为正文。
@ApiOperation({ summary: 'Resource for sign in user.' })
@ApiResponse({ status: 200, type: TokensDto })
@Post('/sign-in')
async signIn(@Body() signInUserDto: SignInUserDto) {
return this.userService.signIn(signInUserDto);
}
然后,在前端,我安装了cookie
和@types/cookie
,在这个前端端点的 headers 中,我只是从 body 有效负载中序列化了这个刷新令牌,并从中删除。
import { NextApiRequest, NextApiResponse } from "next";
import { AxiosError } from "axios";
import { api } from "../../../api";
import { serialize } from 'cookie';
export default async (
req: NextApiRequest,
res: NextApiResponse
) => {
try {
const { data } = await api.post('/user/sign-in', req.body)
res.setHeader('Set-Cookie', serialize(
'_rt',
data._rt,
{ path: '/', httpOnly: true })
);
delete data._rt
return res.json(data)
} catch (error) {
return res
.status((error as AxiosError).response?.status as number)
.json((error as AxiosError).response?.data);
}
}
它工作得很好,我不再有这个Node.js
错误,因为Express
响应 class 的响应,我可以设置 cookie。
我通过使用fastify
以更好的方式改进了这段代码,并且在整个管道中 cookie 设置在 header 中。 首先,在后端安装@fastify/cookie
和@nestjs/platform-fastify
。 然后,将其添加到文件中,您将在其中启动Nest.js
应用程序:
import {
FastifyAdapter,
NestFastifyApplication
} from '@nestjs/platform-fastify';
import { fastifyCookie } from '@fastify/cookie';
async function bootstrap() {
const PORT = process.env.PORT || 3002;
const app = await NestFactory.create<NestFastifyApplication>(
AppModule,
new FastifyAdapter()
);
await app.register(fastifyCookie, {
secret: 'my-secret'
});
这将允许您使用来自FastifyReply
的fastify
,这将消除此Node.js
错误作为响应 class:
import { FastifyReply } from 'fastify';
@ApiTags('User')
@Controller('user')
export class UserController {
constructor(private userService: UserService) {}
@Post('/sign-in')
async signIn(
@Body() signInUserDto: SignInUserDto,
@Res({ passthrough: true }) res: FastifyReply
) {
const { _at, _rt } = await this.userService.signIn(signInUserDto);
res.setCookie('_rt', _rt);
return res.send(_at);
}
...
最后一步,在前端端点上,使用cookie
解析这个 cookie 并将其发送到前端。
const { data, headers } = await api.post('/user/sign-in', req.body)
if (headers["set-cookie"]) {
const refreshToken = headers["set-cookie"][0].split('=')[1];
res.setHeader('Set-Cookie', serialize(
'_rt', refreshToken, { path: '/', httpOnly: true })
);
}
return res.json(data)
这是我发现的最好方法,因为它允许您通过所有管道发送 header 中的 cookie,而不是在正文中然后删除它,并且此解决方案消除了这个奇怪Node.js
错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.