Encountering difficulties with the JWTModule in NestJS. I keep receiving this error message, even after passing the secret directly into the configuration instead of through my env file. I'm unsure of what the issue might be.
Error: secretOrPrivateKey must have a value
Here's a brief overview of how it should function:
- The client makes a call to /auth/login with { username: string, password: string }
- The LocalStrategy Guard invokes the AuthService's validateUser method, which calls ldapServices authenticateUser method and returns the user.
- Following that, I need to retrieve the user data from LDAP and merge it with some user data we have stored in our MongoDB database. This aspect is functioning correctly.
- After passing through the guard, the AuthService's login method will be called. This method should create and sign the payload with the JWT, utilizing the JwtService provided by NestJS. However, this is where the problem arises.
Below are the files along with their respective code snippets:
app.controller.ts
import { Controller, Get, Post, Request, UseGuards } from '@nestjs/common';
import { AppService } from './app.service';
import { AuthService } from './providers/auth/auth.service';
import { LocalAuthGuard } from './providers/auth/local.strategy';
@Controller()
export class AppController {
constructor(private readonly authService: AuthService) {}
@UseGuards(LocalAuthGuard)
@Post('/auth/login')
async login(@Request() req) {
return this.authService.login(req.user);
}
}
auth.module.ts
import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
import { UserModule } from './../../endpoints/user/user.module';
import { PassportModule } from '@nestjs/passport';
import { LocalStrategy } from './local.strategy';
import { JwtModule, JwtService } from '@nestjs/jwt';
import { UserService } from './../../endpoints/user/user.service';
import { LdapService } from './../ldap/ldap-service';
import { jwtConstants } from './constants';
import { JwtStrategy } from './jwt.strategy';
@Module({
imports: [
UserModule,
PassportModule,
JwtModule.register({
secret: '2I*5f5OE9tlGIbg*3Q*C',
signOptions: { expiresIn: '12h' },
}),
],
providers: [AuthService, LocalStrategy, LdapService],
controllers: [AuthController],
exports: [AuthService],
})
export class AuthModule {}
auth.service.ts
import { Injectable } from '@nestjs/common';
import { LdapService } from '../ldap/ldap-service';
import { UserService } from './../../endpoints/user/user.service';
import { JwtService } from '@nestjs/jwt';
@Injectable()
export class AuthService {
constructor(
private readonly ldapService: LdapService,
private readonly userService: UserService,
private readonly jwtService: JwtService
) {}
async validateUser(username: string, pass: string): Promise<any> {
const authenticated = await this.ldapService.authenticateUser(
username,
pass,
);
if (authenticated === true) {
console.log(authenticated, username, pass)
return await this.userService.getUserById(username);
}
return null;
}
async login(user: any) {
const payload = { ...user, sub: user.accountName };
console.log(process.env.JWT_SECRET, payload);
return {
access_token: this.jwtService.sign(payload),
};
}
}
local.strategy.ts
import { Strategy } from 'passport-local';
import { AuthGuard, PassportStrategy } from '@nestjs/passport';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { AuthService } from './auth.service';
@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
constructor(private authService: AuthService) {
super();
}
async validate(username: string, password: string): Promise<any> {
const user = await this.authService.validateUser(username, password);
if (!user) throw new UnauthorizedException();
return user;
}
}
@Injectable()
export class LocalAuthGuard extends AuthGuard('local') {}
I believe I'm overlooking something minor. Any assistance would be greatly appreciated.