I\'m failed to compile with this error:
Nest can\'t resolve dependencies of the JWT_MODULE_OPTIONS (?). Please make sure that the argument at index [0] is available
You can make a separate module for it (SharedModule)
make sure you have the following packages installed
npm i --save @nestjs/jwt
npm i --save @nestjs/passport
(optional, if you go with MongoDB/Mongoose)
npm i --save @nestjs/mongoose
shared.module.ts
@NgModule({
imports: [
PassportModule.register({
defaultStrategy: 'jwt',
}),
JwtModule.register({
secret: process.env.JWT_SECRET_KEY,
signOptions: {
expiresIn: '2 days',
},
}),
],
providers: [JwtStrategy],
exports: [JwtStrategy, PassportModule]
})
jwt.strategy.ts
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(@InjectModel('User') private collection: Model<User>) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: process.env.JWT_SECRET_KEY,
});
}
async validate(payload: JwtPayload): Promise<User> {
const { username } = payload;
const user = await this.collection.findOne({ username });
if (!user) {
throw new UnauthorizedException('JwtStrategy unauthorized');
}
return user;
}
}
Now where you want to use it, just import in your module SharedModule. In your controllers use the following decorator
@UseGuards(AuthGuard())
I somehow got it to work by adding
JwtModule.registerAsync({
imports: [ConfigModule], // Missing this
useFactory: async (configService: ConfigService) => ({
signOptions: {
expiresIn: config.expiresIn,
},
secretOrPrivateKey: config.jwtSecret,
}),
inject: [ConfigService],
}),
in the app.module.ts and auth.module.ts
First, you are mixing the TypeORMModule configuration with the JWTModule configuration.
According to @nestjs/jwt
source code (and docs), secretOrPrivateKey
and signOptions
. All the other parameters seem to be part of the TypeORMModule configuration.
Second, the ConfigService (which is dependency [0] of the JWT module) does not seem to exist anywhere in your code. So you are missing an import to a module where the ConfigService exists inside.
This is why the dependency load is failing (and that is what the error is throwing means)
Note that in your code you are missing an import of a module (ConfigModule
in the following sample), which is the module that holds the ConfigService. Otherwise there is no way to inject this ConfigService from nowhere!
JwtModule.registerAsync({
imports: [ConfigModule], // Missing this
useFactory: async (configService: ConfigService) => ({
signOptions: {
expiresIn: config.expiresIn,
},
secretOrPrivateKey: config.jwtSecret,
}),
inject: [ConfigService],
}),