我试图通过将秘密 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
)
}
}