I have a project and I need to implement JWT service. I have followed the nest.js docs for this. In the file constants.ts I export an object that has a secret for key and my process.env for value
export const jwtConstants = () => ({
secret: process.env.SECRET_JWT,
});
and this doesn't work. I have tried with a key directly in value and that works. I don't know why I can't access my env file in this file. This is my auth module:
import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
import { UserService } from '../user/user.service';
import { MongooseModule } from '@nestjs/mongoose';
import { User, UserSchema } from '../user/user.schema';
import { JwtModule } from '@nestjs/jwt';
import { jwtConstants } from './constants';
@Module({
imports: [
MongooseModule.forFeature([{ name: User.name, schema: UserSchema }]),
JwtModule.register({
global: true,
secret: jwtConstants.secret,
signOptions: { expiresIn: '60s' },
}),
],
providers: [AuthService, UserService],
controllers: [AuthController],
})
export class AuthModule {}
my auth service
import { Injectable } from '@nestjs/common';
import { UserService } from '../user/user.service';
import { AuthDto } from './dto/auth.dto';
import { JwtService } from '@nestjs/jwt';
import * as argon2 from 'argon2';
@Injectable()
export class AuthService {
constructor(
private userService: UserService,
private jwtService: JwtService,
) {}
async signIn(authDto: AuthDto): Promise<{ access_token: string }> {
const user = await this.userService.findOne(authDto.email);
try {
if (await argon2.verify(user.password, authDto.password)) {
const payload = {
userName: user.firstName,
userLastName: user.lastName,
userPhone: user.phone,
userEmail: user.email,
};
return {
access_token: await this.jwtService.signAsync(payload),
};
} else {
console.log('doesn\t match');
}
} catch (error: any) {
console.log('doesn\t work');
}
}
}
and my app module with the ConfigModule.forRoot
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { ConfigModule } from '@nestjs/config';
import { UserModule } from './user/user.module';
import { CompanyModule } from './company/company.module';
import { CallForBidsModule } from './callForBids/call-for-bids.module';
import { AuthModule } from './auth/auth.module';
import { User, UserSchema } from './user/user.schema';
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
envFilePath: '.env',
}),
MongooseModule.forRoot(process.env.MONGO_DB_URL, {
dbName: process.env.MONGO_DB_DATABASE_NAME,
auth: {
username: process.env.MONGO_DB_USERNAME,
password: process.env.MONGO_DB_PASSWORD,
},
}),
MongooseModule.forFeature([{ name: User.name, schema: UserSchema }]),
// feature module
UserModule,
CompanyModule,
CallForBidsModule,
AuthModule,
],
controllers: [],
providers: [],
})
export class AppModule {}
I have tried changing the lib and added the dotenv lib for Nestjs but got the same result. I have tried with the key directly that worked but I need to use the .envfile Rebuild the project doesn't work either.
With your current jwtConstants
you should be accessing the secret like jwtConstants().secret
as it's a function export.
However, as you're using @nestjs/config
, the better approach would be to use JwtModule.registerAsync
and inject the ConfigService
to the JwtModule
rather than relying on process.env
, so ensure that the values are coming from where you think they are. This would look something like
import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
import { UserService } from '../user/user.service';
import { MongooseModule } from '@nestjs/mongoose';
import { User, UserSchema } from '../user/user.schema';
import { JwtModule } from '@nestjs/jwt';
import { jwtConstants } from './constants';
@Module({
imports: [
MongooseModule.forFeature([{ name: User.name, schema: UserSchema }]),
JwtModule.registerAsync(
inject: [ConfigService],
useFactory: (config: ConfigService) => ({
global: true,
secret: config.get('SECRET_JWT'),
signOptions: { expiresIn: '60s' },
}),
}),
],
providers: [AuthService, UserService],
controllers: [AuthController],
})
export class AuthModule {}
You can also do a similar approach with your MongooseModule
using a forRootAsync
to inject the ConfigService
and get the env variables from there