【问题标题】:UnauthorizedException is deliver as Internal Server ErrorUnauthorizedException 作为内部服务器错误传递
【发布时间】:2022-08-11 06:21:38
【问题描述】:

我正在尝试创建一个共享 Guard 作为外部库,以便跨服务导入和使用。我没有做任何比what is described in some guides 更特别的事情,而是代码将驻留在共享库中的特殊性。一切正常,但异常返回 401 错误。

我的后卫看起来像这样:

import { Injectable } from \'@nestjs/common\';
import { AuthGuard } from \'@nestjs/passport\';

@Injectable()
export class MainGuard extends AuthGuard(\'jwt\') {}

没有其他的。如果我在服务文件夹中使用它,它可以工作,但是当我像在他们自己的库中一样移动时,响应会发生变化。

我在服务中使用的方式没有什么特别的:

import { MainGuard } from \'shared-guard-library\';
import { Controller, Get, UseGuards } from \'@nestjs/common\';
import { SomeService } from \'./some.service\';

@Controller()
export class SomeController {
  constructor(private someService: SomeService) {}

  @Get(\'/foo\')
  @UseGuards(MainGuard)
  async getSomething(): Promise<any> {
    return this.someService.getSomething();
  }
}

客户端收到错误 500:

http :3010/foo
HTTP/1.1 500 Internal Server Error
Connection: keep-alive
Content-Length: 52
Content-Type: application/json; charset=utf-8
Date: Thu, 09 Dec 2021 04:11:42 GMT
ETag: W/\"34-rlKccw1E+/fV8niQk4oFitDfPro\"
Keep-Alive: timeout=5
Vary: Origin
X-Powered-By: Express

{
    \"message\": \"Internal server error\",
    \"statusCode\": 500
}

在日志中显示:

[Nest] 93664  - 12/08/2021, 10:11:42 PM   ERROR [ExceptionsHandler] Unauthorized
UnauthorizedException: Unauthorized
    at MainGuard.handleRequest (/sharedGuardLibrary/node_modules/@nestjs/passport/dist/auth.guard.js:68:30)
    at /sharedGuardLibrary/node_modules/@nestjs/passport/dist/auth.guard.js:49:128
    at /sharedGuardLibrary/node_modules/@nestjs/passport/dist/auth.guard.js:86:24
    at allFailed (/sharedGuardLibrary/node_modules/passport/lib/middleware/authenticate.js:101:18)
    at attempt (/sharedGuardLibrary/node_modules/passport/lib/middleware/authenticate.js:174:28)
    at Object.strategy.fail (/sharedGuardLibrary/node_modules/passport/lib/middleware/authenticate.js:296:9)
    at Object.JwtStrategy.authenticate (/sharedGuardLibrary/node_modules/passport-jwt/lib/strategy.js:96:21)
    at attempt (/sharedGuardLibrary/node_modules/passport/lib/middleware/authenticate.js:360:16)
    at authenticate (/sharedGuardLibrary/node_modules/passport/lib/middleware/authenticate.js:361:7)
    at /sharedGuardLibrary/node_modules/@nestjs/passport/dist/auth.guard.js:91:3

日志告诉我抛出了正确的异常,但在某些时候被忽略了,我不知道原因。再次:同一个项目中的相同代码有效。

我看了一下原来的类和I don\'t see any particular way to treat the exception

任何线索或指南将不胜感激。

  • 如果同一项目中的相同代码有效,请尝试rm -rf node_modules 并再次安装(不要触摸锁定文件)
  • 已经尝试过类似的相关事情,例如使用服务和库清理 npm 缓存;结果相同

标签: nestjs nestjs-passport nestjs-jwt


【解决方案1】:

因此,这恰好是 Typescript 的一个“特性”,以及 JavaScript 对象相等性的一般工作原理。所以在 Nest 的 BaseExceptionFilter 中有一个检查 exception instanceof HttpException,通常情况下,UnauthorizedException 会是这样的一个实例,但是因为这是一个库,所以需要考虑一些事情。

  1. 您正在使用的所有 NestJS 依赖项成为peerDependencies。这确保了在安装库时,只有一个 @nestjs/* 包的结果包。

  2. 在本地开发过程中,您需要注意确保您不会解析同一包的多个实例(即使它是完全相同的版本,JavaScript { hello: 'world' } === { hello: 'world' } // false)。为了解决这个问题,npm/yarn/pnpm link 之类的东西应该不是可以使用,但您应该将distpackage.json 复制到主应用程序的node_modules/&lt;package_name&gt; 目录。

    一个。另一种选择是使用像Nest's monorepo approachNx 这样的monorepo 工具,它们具有单一包版本方法,并使用库的路径而不是内部链接。

    如果您遵循这一点,当您的生产应用程序安装 npm 库时,一切都会正常运行。这肯定是一个烦恼,但它是 JavaScript 工作方式的副作用

【讨论】:

  • 没有你的帮助,我永远不会想出解释。太感谢了!
  • 你是怎么解决这个问题的?我有同样的问题,我有一个带有 pnpm 的 Rust monorepo,在将nestjs 更新到 8.2.0 后它响应 500 错误而不是 401。有什么建议吗?
  • 如果不回答问题,为什么这个答案会被接受?
  • @GabrielLlamas 但它确实回答了这个问题。 UnauthorizedExcepotion 被视为 Internal Server Error,因为由于 JavaScript 处理对象相等性的方式,instanceof HttpException 检查失败。
【解决方案2】:

我在 monorepo 中的自定义身份验证包中遇到了类似的问题。

我有一个自定义的身份验证库,它公开了 AuthModule、JwtAuthGuard 和一些实用程序功能。所有需要的软件包都安装在我的库下,因此使用它的任何其他项目都没有安装其他版本的依赖项。不幸的是,使用自定义防护导致内部服务器错误。

我通过添加全局自定义异常过滤器解决了这个问题。它寻找一种解决方法,但至少解决了这个问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-01
    • 2021-10-27
    • 1970-01-01
    • 2013-07-14
    • 2012-10-12
    • 1970-01-01
    相关资源
    最近更新 更多