#Jwt Auth guard instantiates twice whenever I use it within 2 modules.
21 messages · Page 1 of 1 (latest)
show your code here related to it
I have 3 modules:
AppModule,
@Module({
imports: [
AuthModule,
UserModule,
],
controllers: [],
providers: [],
})
export class AppModule {}
AuthModule,
@Module({
exports: [
AuthService,
JwtStrategy,
JwtAuthGuard,
JwtModule
],
imports: [
PassportModule,
JwtModule.register({
secret: '123', //I understand I HAVe to change this
}),
],
controllers: [AuthController],
providers: [
AuthService,
JwtAuthGuard,
JwtStrategy,
],
})
export class AuthModule {}
UsersModule,
@Module({
imports: [
AuthModule,
],
exports: [UserService],
controllers: [UserController],
providers: [UserService],
})
export class UserModule{}
and this is my jwt,
@Injectable({ scope: Scope.DEFAULT })
export class JwtAuthGuard extends AuthGuard('jwt') {
constructor(
private readonly authService: AuthService
) {
console.log("New instance");
super();
}
async canActivate(
context: ExecutionContext,
): Promise<boolean> {
..
}
And jwt is instantiated how many times I use "@UseGuards(JwtAuthGuard)"
Did you try to register it globally ?
JwtModule.register({
global: true,
...
})
it still created 2 instances..
how about not to export jwt strategy, jwt auth guard and jwt auth module
@tulip radish
why you need to export them?
when i create auth using passport i just register as a provider not to export them
because I have some custom logic inside the canActivate method inside the jwt auth guard.
and exporting the auth service was the only way to make the jwt auth service able to be instantiated with the auth service injected.
the idea was a singleton, but this was a good bandaid fix while I try to find out WHY nest does not just use the singleton.
The auth guard should not go into providers, only the strategy
Guards, interceptors or pipes never go to providers, they're bound to controllers, or provided via APP_GUARD/etc
So the second instantiation happens because Nest automatically instantiates everything in providers. So you essentially have an instance JwtAuthGuard laying around in providers, but that one is never used.
And jwt is instantiated how many times I use "@UseGuards(JwtAuthGuard)"
Yes. Or, at least - once in every module where it is used. Because it uses DI from the module, and the implementation of dependencies can be different there.
then how can I inject my auth service into the provider and still use it everywhere with 1 instance??
The auth service should be exported from the auth module. The auth module should be imported in the module where the guard is used, so that the guard can inject it
(The guard instance in providers only sits there and is never used because that's not how you bind a guard)
There will be as many guard instances as the modules where it is used, unless you bind the guard globally.
I tried adding the guard as global by doing the following:
providers: [
{
provide: APP_GUARD,
useClass: JwtAuthGuard
}
]
In the Auth module, this landed me nowhere... It just worsened what I already done because I was unable to hit any endpoints I've done that require no authorization... Like login.
And adding it with app.useGlobalGuard would probably fail BECAUSE **Auth service inside the guard is undefined... **
How am I meant to do this exactly?