繁体   English   中英

错误:这是由 Node.js 中的错误或 Node.js 内部的错误使用引起的

[英]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。

所以,我的问题是 - 这个错误是什么? 我可以忽略它吗? 如果没有,那我该如何解决?

提前致谢!

TL;博士

最后,我能够修复这个错误,首先,正如我所说,我经历了 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'
  });

这将允许您使用来自FastifyReplyfastify这将消除此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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM