I would like to add my jwt service as global service. But its not work in CanActivate(my guard). More precisely, he comes there, but does not have a secret key
This is my code: Register service as global
forwardRef(() => UsersModule),
{
...JwtModule.registerAsync({
useFactory: (configService: ConfigService) => ({
secret: configService.get<string>('PRIVATE_KEY'),
signOptions: {
expiresIn: '24h',
},
}),
inject: [ConfigService],
}),
global: true,
},
My Jwt
@Injectable()
export class JwtAuthGuard implements CanActivate {
constructor(private jwtService: JwtService) {}
canActivate(
context: ExecutionContext,
): boolean | Promise<boolean> | Observable<boolean> {
const req = context.switchToHttp().getRequest();
try {
const authHeader = req.headers.authorization;
const [bearer, token] = authHeader.split(' ');
if (bearer.toLowerCase() !== 'bearer' || !token)
throw new UnauthorizedException({
message: 'Пользователь не авторизован',
});
const user = this.jwtService.verify(token);
req.user = user;
return true;
} catch (e) {
console.log(e);
throw new UnauthorizedException({
message: 'Пользователь не авторизован',
});
}
}
}
My auth module
@Module({
controllers: [AuthController],
providers: [JwtService],
imports: [forwardRef(() => UsersModule)],
exports: [],
})
export class AuthModule {}
CodePudding user response:
To take @nestjs/jwt
's JwtModule
and make it global, you need to add it to a global wrapper module and export the JwtModule
in that wrapper. Something like this:
@Global()
@Module({
imports: [
JwtModule.registerAsync({
useFactory: (configService: ConfigService) => ({
secret: configService.get<string>('PRIVATE_KEY'),
signOptions: {
expiresIn: '24h',
},
}),
inject: [ConfigService],
}),
],
exports: [JwtModule]
})
export class GlobalJwtModule {}
Now as long as GlobalJwtModule
is added to your AppModule
the JwtService
will be globally injectable
CodePudding user response:
If you haven't provided Strategies to AuthModule
it will not trigger CanActive implementation.
@Module({
imports: [
forwardRef(() => UsersModule),
JwtModule.registerAsync({
imports: [ConfigModule],
useFactory: async (configService: ConfigService) => ({
secret: configService.get<string>('PRIVATE_KEY'),
signOptions: {
expiresIn: '1d',
},
}),
inject: [ConfigService],
}),
],
controllers: [AuthController],
providers: [AuthService, LocalStrategy, JwtStrategy], <=== important here!!
exports: [AuthService],
})
Moreover, if you want to use the Jwt App Guard as global you might need to provide it to AppModule
in app.module.ts
like this.
@Module({
imports: [
ConfigModule.forRoot({ isGlobal: true }),
UsersModule,
AuthModule,
],
controllers: [AppController],
providers: [
AppService,
{
provide: APP_GUARD,
useClass: JwtAuthGuard,
},
],
})
export class AppModule {}