I had a lot of research and I keep getting the same error. I'm pretty sure that it has something to do with ConfigModule because the app works well when I launch it in localhost, but when I execute it in production I get -> TypeError: JwtStrategy requires a secret or key (means the app can't see the .env secret variable I think) after dig into several webs I share the module that is doing all this:
import { Module } from "@nestjs/common";
import { APP_GUARD } from "@nestjs/core";
import { AtGuard } from "@enlazo/nestjscommon/dist/guards";
import { ConfigModule } from "@nestjs/config";
import { DatabaseModule } from "@enlazo/bd_ibm/dist";
import { AppDashboardDesarrolloController } from "./app-dashboard-desarrollo.controller";
import { AppDashboardDesarrolloService } from "./app-dashboard-desarrollo.service";
import { MailModule } from "@enlazo/mail/dist";
import { AtStrategy } from "@enlazo/nestjscommon/dist/strategies";
import { JwtModule } from "@nestjs/jwt";
@Module({
imports: [DatabaseModule, ConfigModule.forRoot({ isGlobal: true }), MailModule, JwtModule.register({ secretOrPrivateKey: process.env.AT_SECRET })],
controllers: [AppDashboardDesarrolloController],
providers: [
AppDashboardDesarrolloService,
AtStrategy,
{
provide: APP_GUARD,
useClass: AtGuard
}
]
})
export class AppDashboardDesarrolloModule {}
The Atguard file:
import { ExecutionContext, HttpException, Injectable, UnauthorizedException } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { AuthGuard } from '@nestjs/passport';
import { ErrorDto, Notification } from '../dto';
@Injectable()
export class AtGuard extends AuthGuard('jwt') {
constructor(private reflector: Reflector) {
super();
}
canActivate(context: ExecutionContext) {
// console.log("AtGuard");
const isPublic = this.reflector.getAllAndOverride('isPublic', [
context.getHandler(),
context.getClass(),
]);
if (isPublic) return true;
return super.canActivate(context);
}
handleRequest(err, user, info) {
// console.log("JWT AUTH", err, user, info);
// You can throw an exception based on either "info" or "err" arguments
if (err || !user) {
if (info) {
if(info.name == "TokenExpiredError") {
throw new UnauthorizedException(new ErrorDto("accessTokenExpired", Notification.warning, false));
}
throw new UnauthorizedException(new ErrorDto("Error de autenticación", Notification.warning, false));
}
throw err;// || new UnauthorizedException("accessTokenExpired");
}
return user;
}
}
And finaly the Strategy:
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { JwtPayload } from '../types';
@Injectable()
export class AtStrategy extends PassportStrategy(Strategy, 'jwt') {
constructor(config: ConfigService) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderWithScheme('Enlazo'),
secretOrKey: config.get<string>('AT_SECRET'),
});
}
validate(payload: JwtPayload) {
return payload;
}
}
Note that the first file I share is importing the next two from a dependency