0

我试图通过将秘密 JWT 密钥隐藏到本地存储在应用程序根目录的 dotenv 文件中来保护我的应用程序,但是文档对我来说不够清楚,并且在运行测试时我不断收到此错误:

 console.error
    Error: secretOrPrivateKey must have a value
        at Object.module.exports [as sign] (/Users/amehmeto/HeroesJobs/BFF/bff-candidates/node_modules/jsonwebtoken/sign.js:107:20)
        at JwtService.sign (/Users/amehmeto/HeroesJobs/BFF/bff-candidates/node_modules/@nestjs/jwt/dist/jwt.service.js:27:20)
        at AuthService.generateToken (/Users/amehmeto/HeroesJobs/BFF/bff-candidates/src/auth/auth.service.ts:62:37)
        at AuthService.verifySmsCode (/Users/amehmeto/HeroesJobs/BFF/bff-candidates/src/auth/auth.service.ts:49:19)
        at processTicksAndRejections (internal/process/task_queues.js:97:5)
        at Object.<anonymous> (/Users/amehmeto/HeroesJobs/BFF/bff-candidates/src/auth/auth.service.spec.ts:83:30)

      49 |       return this.generateToken(candidateId)
      50 |     } catch (e) {
    > 51 |       console.error(e)
         |               ^
      52 |       throw new HttpException(
      53 |         ResponseMessage.INVALID_CODE,
      54 |         HttpStatus.FORBIDDEN

      at AuthService.verifySmsCode (auth/auth.service.ts:51:15)
      at Object.<anonymous> (auth/auth.service.spec.ts:83:30)

这是.env

JWT_SECRET=secretKey

这是src/app.module.ts

import { Module } from '@nestjs/common'
import { StatusModule } from './status/status.module'
import { CitiesModule } from './cities/cities.module'
import { PopupModule } from './popup/popup.module'
import { CandidateModule } from './candidate/candidate.module'
import { NotificationModule } from './notification/notification.module'
import { ChatModule } from './chat/chat.module'
import { AuthModule } from './auth/auth.module'
import { SkillInviteModule } from './skill-invite/skill-invite.module'
import { ConfigModule } from '@nestjs/config'

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
    }),
    StatusModule,
    CitiesModule,
    PopupModule,
    CandidateModule,
    NotificationModule,
    ChatModule,
    AuthModule,
    SkillInviteModule,
  ],
})
export class AppModule {}

测试文件:

describe('AuthService', () => {
  let service: AuthService
  let authRepository: AuthRepository
  let authGateway: AuthGateway
  let jwtService: JwtService

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      imports: [
        JwtModule.register({
          secret: process.env.JWT_SECRET,
        }),
      ],
      providers: [AuthService, AuthRepository, AuthGateway],
    }).compile()

    service = module.get<AuthService>(AuthService)
    authRepository = module.get<AuthRepository>(AuthRepository)
    authGateway = module.get<AuthGateway>(AuthGateway)
    jwtService = module.get<JwtService>(JwtService)
  })

  it('should be defined', () => {
    expect(service).toBeDefined()
  })


[...]

    it('should generate a token that expires within one hour when code is valid', async () => {
      const payload = { candidateId: '1' }

      const verifyResponse = await service.verifySmsCode(phoneNumber, code)
      expect(verifyResponse).toHaveProperty(
        'access_token',
        jwtService.sign(payload)
      )
      expect(verifyResponse).toHaveProperty('expires_in', 1000 * 60 * 60)
    })

最后是被测代码:


  async verifySmsCode(
    phoneNumber: string,
    code: string
  ): Promise<VerifyResponseObject> {
    try {
      const candidateId = await this.authRepository.verifySmsCode(
        phoneNumber,
        code
      )
      return this.generateToken(candidateId)
    } catch (e) {
      console.error(e)
      throw new HttpException(
        ResponseMessage.INVALID_CODE,
        HttpStatus.FORBIDDEN
      )
    }
  }
4

2 回答 2

1

您必须先导dotenv入库并对其进行配置,然后才能使用.env. 添加require('dotenv').config()main.ts将解决您的问题。

于 2020-10-02T07:48:37.740 回答
1

我认为这可以通过在你的单元测试中导入ConfigModule来解决:TestingModule

 const module: TestingModule = await Test.createTestingModule({
      imports: [ConfigModule.forRoot()],
      providers: [AuthService, AuthRepository, AuthGateway],
    }).compile()
于 2020-10-04T09:17:51.083 回答