使用 NestJS 解决依赖关系
Resolving dependencies with NestJS
我有相当深厚的 MERN stack/Javascript 背景,我今天正在尝试新技术:NestJS,据我所知,它是围绕 TypeScrypt 和 OOP 编程构建的。
我正在尝试构建一个简单的 API,并通过 JSON Web 令牌进行身份验证,因此我按照文档所述实施了 Guard
。请注意,我没有通过使用 Passport
及其策略来走完整的“NestJS”路线。在发现新技术时,我更喜欢用尽可能少的库来实现我自己的东西,而不是对我第二天不会记得的教程进行完整的复制粘贴。
我成功编写了简单的路由并使用 Mongoose 和 MongoDB 连接了项目,但我偶然发现了一个关于 NestJS 模块 imports/exports 层次结构的奇怪错误。
错误如下:
[Nest] 37422 - 03/25/2022, 4:49:57 PM ERROR [ExceptionHandler] Nest can't resolve dependencies of the JwtAuthGuard (?). Please make sure that the argument ConfigService at index [0] is available in the UsersModule context.
现在我使用 ConfigModule
,特别是 ConfigService
来访问我的环境变量。我将在我的 JwtAuthGuard
中需要它来访问我的私钥和各种 JWT 配置到 create/verify 令牌。
我声明我的 JwtAuthGuard
如下:
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { Observable } from 'rxjs';
import { ConfigService } from '@nestjs/config';
const jwt = require('jsonwebtoken');
@Injectable()
export class JwtAuthGuard implements CanActivate {
constructor(private config: ConfigService) {}
canActivate(
context: ExecutionContext,
): boolean | Promise<boolean> | Observable<boolean> {
const req = context.switchToHttp().getRequest();
// extract Authorization header and verify it here
// return true/false depending on jwt.verify return
return false;
}
createToken() {
return jwt.sign(
{ issuer: this.config.get('JWT_ISSUER') },
this.config.get('JWT_PRIVATE_KEY'),
{ algorithm: this.config.get('JWT_ALGORITHM') },
);
}
}
当然,我在 JwtAuthModule
:
中导入 ConfigModule
import { Module } from '@nestjs/common';
import { JwtAuthGuard } from './guard';
import { ConfigModule } from '@nestjs/config';
@Module({
exports: [JwtAuthGuard],
providers: [JwtAuthGuard],
imports: [ConfigModule],
})
export class JwtAuthModule {}
我的 UsersModule
(最初)看起来像这样:
import { MongooseModule } from '@nestjs/mongoose';
import { User, UserSchema } from './schemas/users';
import { UsersController } from './controller';
import { UsersProvider } from './service';
import { JwtAuthModule } from '../jwt-auth/module';
import { ConfigModule } from '@nestjs/config';
@Module({
imports: [
MongooseModule.forFeature([{ name: User.name, schema: UserSchema }]),
JwtAuthModule,
],
controllers: [UsersController],
providers: [UsersProvider],
exports: [
MongooseModule.forFeature([{ name: User.name, schema: UserSchema }]),
UsersProvider,
],
})
export class UsersModule {}
我说 最初 因为,在仔细阅读错误之后,我摆弄了代码并看到了当我:
- 将
ConfigModule
添加到 UsersModule
中的 导入列表 ,就在 JwtAuthModule
之前
- 将
ConfigModule
添加到 JwtAuthModule
中的 exports 列表
错误消失,一切正常。
问题是:为什么我必须让 ConfigModule
可供 UsersModule
使用,而实际上它本身并不真正需要它?
编辑:忘记添加上下文:我在我的 UsersController
routes/handlers.
之一上使用 @UseGuards(JwtAuthGuard)
装饰器
根据错误,我只是假设您的 UsersController
中某处有 @UseGuards(JwtAuthGuard)
。通过这个,Nest 将尝试在 UsersModule
上下文的上下文中实例化 JwtAuthGuard
,这意味着使用它可用的依赖项。由于您的 JwtAuthGuard
使用 ConfigService
,ConfigModule
的导出需要可用,这可以通过让 JwtAuithModule
导入和导出 ConfigModule
来完成] 或者让 UsersModule
导入 ConfigModule
.
exports: [JwtAuthGuard]
还不够的原因有点奇怪,因为增强器不是提供者,因为它们每次都使用相同的 pre-built 上下文来构建。它们在技术上不属于模块(至少在大多数情况下,存在超出此答案范围的例外情况)所以即使 JwtAuthModule
确实导出 JwtAuthGuard
它不实际上意味着 Nest 将使用导出的提供程序从 @UseGuards()
中的 UserModule
中创建实例 UserController
.
希望一切都有意义
我有相当深厚的 MERN stack/Javascript 背景,我今天正在尝试新技术:NestJS,据我所知,它是围绕 TypeScrypt 和 OOP 编程构建的。
我正在尝试构建一个简单的 API,并通过 JSON Web 令牌进行身份验证,因此我按照文档所述实施了 Guard
。请注意,我没有通过使用 Passport
及其策略来走完整的“NestJS”路线。在发现新技术时,我更喜欢用尽可能少的库来实现我自己的东西,而不是对我第二天不会记得的教程进行完整的复制粘贴。
我成功编写了简单的路由并使用 Mongoose 和 MongoDB 连接了项目,但我偶然发现了一个关于 NestJS 模块 imports/exports 层次结构的奇怪错误。
错误如下:
[Nest] 37422 - 03/25/2022, 4:49:57 PM ERROR [ExceptionHandler] Nest can't resolve dependencies of the JwtAuthGuard (?). Please make sure that the argument ConfigService at index [0] is available in the UsersModule context.
现在我使用 ConfigModule
,特别是 ConfigService
来访问我的环境变量。我将在我的 JwtAuthGuard
中需要它来访问我的私钥和各种 JWT 配置到 create/verify 令牌。
我声明我的 JwtAuthGuard
如下:
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { Observable } from 'rxjs';
import { ConfigService } from '@nestjs/config';
const jwt = require('jsonwebtoken');
@Injectable()
export class JwtAuthGuard implements CanActivate {
constructor(private config: ConfigService) {}
canActivate(
context: ExecutionContext,
): boolean | Promise<boolean> | Observable<boolean> {
const req = context.switchToHttp().getRequest();
// extract Authorization header and verify it here
// return true/false depending on jwt.verify return
return false;
}
createToken() {
return jwt.sign(
{ issuer: this.config.get('JWT_ISSUER') },
this.config.get('JWT_PRIVATE_KEY'),
{ algorithm: this.config.get('JWT_ALGORITHM') },
);
}
}
当然,我在 JwtAuthModule
:
ConfigModule
import { Module } from '@nestjs/common';
import { JwtAuthGuard } from './guard';
import { ConfigModule } from '@nestjs/config';
@Module({
exports: [JwtAuthGuard],
providers: [JwtAuthGuard],
imports: [ConfigModule],
})
export class JwtAuthModule {}
我的 UsersModule
(最初)看起来像这样:
import { MongooseModule } from '@nestjs/mongoose';
import { User, UserSchema } from './schemas/users';
import { UsersController } from './controller';
import { UsersProvider } from './service';
import { JwtAuthModule } from '../jwt-auth/module';
import { ConfigModule } from '@nestjs/config';
@Module({
imports: [
MongooseModule.forFeature([{ name: User.name, schema: UserSchema }]),
JwtAuthModule,
],
controllers: [UsersController],
providers: [UsersProvider],
exports: [
MongooseModule.forFeature([{ name: User.name, schema: UserSchema }]),
UsersProvider,
],
})
export class UsersModule {}
我说 最初 因为,在仔细阅读错误之后,我摆弄了代码并看到了当我:
- 将
ConfigModule
添加到UsersModule
中的 导入列表 ,就在JwtAuthModule
之前
- 将
ConfigModule
添加到JwtAuthModule
中的 exports 列表
错误消失,一切正常。
问题是:为什么我必须让 ConfigModule
可供 UsersModule
使用,而实际上它本身并不真正需要它?
编辑:忘记添加上下文:我在我的 UsersController
routes/handlers.
@UseGuards(JwtAuthGuard)
装饰器
根据错误,我只是假设您的 UsersController
中某处有 @UseGuards(JwtAuthGuard)
。通过这个,Nest 将尝试在 UsersModule
上下文的上下文中实例化 JwtAuthGuard
,这意味着使用它可用的依赖项。由于您的 JwtAuthGuard
使用 ConfigService
,ConfigModule
的导出需要可用,这可以通过让 JwtAuithModule
导入和导出 ConfigModule
来完成] 或者让 UsersModule
导入 ConfigModule
.
exports: [JwtAuthGuard]
还不够的原因有点奇怪,因为增强器不是提供者,因为它们每次都使用相同的 pre-built 上下文来构建。它们在技术上不属于模块(至少在大多数情况下,存在超出此答案范围的例外情况)所以即使 JwtAuthModule
确实导出 JwtAuthGuard
它不实际上意味着 Nest 将使用导出的提供程序从 @UseGuards()
中的 UserModule
中创建实例 UserController
.
希望一切都有意义