NestJS DI inject guard by token

Viewed 232

I have shared code beetwen two apps that using different auth strategy.

I want to create Injection token 'AUTH_GUARD' Angular like

  {
    provide: 'AUTH_GUARD',
    useClass: AuthGuard
  }

and then use it in

@UseGuards(@Inject('AUTH_GUARD')) or @UseGuards('AUTH_GUARD') or @UseGuards(() => Inject('AUTH_GUARD'))
@Controller("/protected")

but UseGuards can not take injection token as input params

1 Answers

Unfortunately guards can't be overriden as this comment in a nestjs issue states:

You can't override enhancers (interceptors, guards, pipes, or filters). You can only override providers.

To emulate your desired behavior what you could do is to have 2 providers - each with it's own logic inside - and then inject one service or another inside your guard depending on a flag.

This injection would be happening when you declare your module which contains the guard by doing something like this:

@Global()
@Module({
  imports: [ConfigModule],
  providers: [
    AuthGuard,
    {
      provide: AuthServiceBehaviour,
      useFactory: (config: ConfigService) => {
        if (config.get('YOUR_FLAG')) {
          return new AuthServiceBehaviour1(config);
        }
        return new AuthServiceBehaviour2();
      },
      inject: [ConfigService],
    },
  ],
})
export class AuthModule {}

Related