secretOrPrivateKey 必须有一个值 - NestJs

问题描述 投票:0回答:4

我在服务器中实现 jwt 时遇到此错误。我正在使用 NestJs 并且正在遵循文档。我一直在这里寻找有关此错误的解决方案,但似乎没有任何作用。 我已将密钥存储在 .env 文件中,在 app.module 中添加 ConfigModule.forRoot() ,这样我就可以成功读取所有环境变量。这是我的代码,如果有人能指出我正确的方向。

app.module.ts

@Module({
  imports: [
    ConfigModule.forRoot(),
    TypeOrmModule.forRoot({
      type: 'postgres',
      host: process.env.DB_HOST,
      port: +process.env.DB_PORT,
      username: process.env.DB_USER,
      password: process.env.DB_PASS,
      database: process.env.DB_NAME,
      entities: ['dist/**/*.entity{.ts,.js}'],
      synchronize: false,
    }),
    UsersModule,
    AuthModule,
    PolsModule,
  ],
  controllers: [UsersController, AuthController, PolsController],
  providers: [UsersService, AuthService, PolsService, JwtService],
})
export class AppModule {}

auth.module.ts

@Module({
  imports: [
    UsersModule,
    PassportModule,
    JwtModule.register({
      secret: process.env.JWT_SECRET_KEY,
      signOptions: { expiresIn: '4h' },
    }),
  ],
  providers: [AuthService, UsersService, LocalStrategy, JwtStrategy],
  controllers: [AuthController],
})
export class AuthModule {}

auth.controller.ts

@Controller('auth')
export class AuthController {
  constructor(
    private authService: AuthService,
    private usersService: UsersService,
  ) {}

  @UseGuards(LocalAuthGuard)
  @Post()
  async login(@Request() req) {
    return this.authService.login(req.user);
  }
}

auth.service.ts

@Injectable()
export class AuthService {
  constructor(
    private usersService: UsersService,
    private jwtService: JwtService,
  ) {}

  async login(user: any) {
    const payload = { username: user.username, sub: user.id };
    console.log(process.env.JWT_SECRET_KEY);
    return {
      access_token: this.jwtService.sign(payload),
    };
  }
}

控制台错误

// console.log(process.env.JWT_SECRET_KEY)
fb8C47vylwS
[Nest] 50225  - 01/07/2022, 17:46:37   ERROR [ExceptionsHandler] secretOrPrivateKey must have a value
Error: secretOrPrivateKey must have a value
    at Object.module.exports [as sign] (/Users/user/dev/backend/pol-api/node_modules/jsonwebtoken/sign.js:107:20)
    at JwtService.sign (/Users/user/dev/backend/pol-api/node_modules/@nestjs/jwt/dist/jwt.service.js:28:20)
    at AuthService.login (/Users/user/dev/backend/pol-api/src/auth/auth.service.ts:26:37)
    at AuthController.login (/Users/user/dev/backend/pol-api/src/auth/auth.controller.ts:29:29)
    at /Users/user/dev/backend/pol-api/node_modules/@nestjs/core/router/router-execution-context.js:38:29
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
    at /Users/user/dev/backend/pol-api/node_modules/@nestjs/core/router/router-execution-context.js:46:28
    at /Users/user/dev/backend/pol-api/node_modules/@nestjs/core/router/router-proxy.js:9:17

正如我所说,我尝试了在其他类似问题中找到的不同潜在解决方案(例如这个),但没有一个答案对我有用。

javascript jwt nest
4个回答
7
投票

我参加聚会迟到了,但我只是在绞尽脑汁解决这个问题,然后找到了解决方案。

问题可能出在 app.module.ts 中的这一行:

providers: [UsersService, AuthService, PolsService, JwtService],

JwtService 不应添加为提供者。如果这样做,它似乎会重置所有已注册的选项。


2
投票

您正在将

ConfigModule
导入到
AppModule
中,但不是作为全局模块导入,因此您的
AuthModule
不知道它。这就是为什么它不知道这个秘密。

您也可以将

ConfigModule
导入到
AuthModule
中,或者从
AppModule
中将其作为全局模块导入。

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
    }),
    ...
  ],
  ...
})
export class AppModule {}

然后在

AuthModule
中使用
JwtModule
异步注册
registerAsync
。使用一个工厂,在其中注入从
ConfigService
导出的
ConfigModule

@Module({
  imports: [
    UsersModule,
    PassportModule,
    JwtModule.registerAsync({
      useFactory: (configService: ConfigService) => {
        return {
          secret: configService.get<string>('JWT_SECRET_KEY'),
          signOptions: { expiresIn: '60s' },
        };
      },
      inject: [ConfigService],
    }),
  ],
  ...
})
export class AuthModule {}

ConfigModule
中导入的
AppModule
会在异步 I/O 操作中读取
.env
文件。通过异步注册
JwtModule
并注入
ConfigService
依赖项,您将使其等待,直到加载
ConfigModule
并读取
.env
文件。只需使用
ConfigService
读取环境变量并进行转换即可。

有关使用

ConfigService
的更多信息可以在 NestJS 的文档中找到。

https://docs.nestjs.com/techniques/configuration#using-the-configservice


0
投票

你可以改变

secret: process.env.JWT_SECRET_KEY

secret: `${process.env.JWT_SECRET_KEY}`

0
投票

尝试从 app.module.ts 中的提供程序中删除

JwtService
AuthService
。同时从 app.module.ts 中的控制器中删除
AuthController

当我遇到同样的错误消息时,这对我有用。虽然我还不完全确定为什么会这样(我对 NestJS 很陌生),但这是我的推理:

您将

AuthModule

(已包含 
AuthController
AuthService
)传递到要导入到 
AppModule
 中。通过在根 (
AuthController
) 级别再次添加 
AuthService
AppModule
,我相信您首先就违背了拥有 
AuthModule
 的目的,并且不使用模块上下文。通过将 
JwtService
 添加到 
AppModule
 提供程序,您可以使用空的来覆盖在 
JwtService
 上下文中注册的 
AuthModule

再次强调,我是 NestJS 的新手,非常欢迎指正。

编辑: 我假设您正在遵循
documentation,不幸的是它没有显示 AppModule。 但是,它们确实链接到 GitHub 存储库,其中仅导入模块(而不是服务):

import { Module } from '@nestjs/common'; import { AppController } from './app.controller'; import { AppService } from './app.service'; import { AuthModule } from './auth/auth.module'; import { UsersModule } from './users/users.module'; @Module({ imports: [AuthModule, UsersModule], controllers: [AppController], providers: [AppService], }) export class AppModule {}
我希望这有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.