NestJS inject service in guard

Viewed 1415

I am pretty new to developing REST APIs using the NestJS framework (started using it last week).

For Authorization purposes I want to implement a CanActivate Guard to my app. This guard simply looks for an authorization header to extract the jwt. Furthermore the user needs to be fetched via a service to get its role and check for the required permission. Additionally there is a @Permission decorator, which is used on protected routes, that takes in a permission string. This decorator file looks like this:

export const PERMISSION_KEY = "requiredPermission"
export const Permission = (permission: string) => {
    return SetMetadata(PERMISSION_KEY, permission);
}

But I am experiencing strange behaviour: Only injecting the Reflector (so I can look up the required permission from the route) is working fine. When now trying to inject a service, let's say AuthService, the constructor of the AuthenticationGuard isn't even called, so the service results in undefined. Event the reflector instance is undefined, though it worked before. Here is how it looks in my authentication.guard.ts:

@Injectable()
export class AuthenticationGuard implements CanActivate {

    constructor(
        private reflector: Reflector, 
        private authService: AuthService
    ) {}

    canActivate(context: ExecutionContext): boolean | Promise<boolean> | Observable<boolean> {
        // ... do some things to extract jwt from header ...

        console.log(this.authService); // Results in undefined

        // This line does not work because reflector also is undefined.
        const requiredPermission = this.reflector.get<string>(PERMISSION_KEY, context.getHandler());
        console.log(requiredPermission);
    
    }
}

This guard is imported as a provider in a feature module called AuthModule:

@Module({
  imports: [
    JwtModule.register({
      secret: "EXTREMELY_SECRET"
    })
  ],
  providers: [
    AuthService, 
    { 
      provide: APP_GUARD, 
      useClass: AuthenticationGuard 
    }
  ],
  controllers: [ AuthController ],
  exports: [
    AuthService
  ]
})
export class AuthModule {}

Now when removing the service from dependency injection and make a console.log, I can see that it gets instantiated as the first dependency of the whole app. Does this maybe cause the service to fail injecting? How would I possibly change fix that?

Or does injecting services not work for guards in general? I think this is not the problem.

Maybe someone can help me with this problem and give me some advice on to fix this issue. Thank you very kindly in advance for your support!

0 Answers
Related