最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Initialize Guard with value - Stack Overflow

programmeradmin1浏览0评论

Is it possible to initialize guard with a specifig value ? For example the current example will not work:

@Module({
  imports: [
    CoreModule,
  ],
  providers: [
    {
      provide: AuthGuard, // while using APP_GUARD works
      useFactory: (configService: ConfigService) => {
        return new AuthGuard(configService.get('some_key'));
      },
      inject: [ConfigService],
    },
  ],
})

While using APP_GUARD for provide will initialise the guard with config value. So it works only for global scope, but not for @UseGuards(AuthGuard)

Is it possible to initialize guard with a specifig value ? For example the current example will not work:

@Module({
  imports: [
    CoreModule,
  ],
  providers: [
    {
      provide: AuthGuard, // while using APP_GUARD works
      useFactory: (configService: ConfigService) => {
        return new AuthGuard(configService.get('some_key'));
      },
      inject: [ConfigService],
    },
  ],
})

While using APP_GUARD for provide will initialise the guard with config value. So it works only for global scope, but not for @UseGuards(AuthGuard)

Share Improve this question edited Feb 6, 2019 at 12:12 Kim Kern 60.7k20 gold badges218 silver badges214 bronze badges asked Feb 6, 2019 at 7:43 user2623505user2623505 3596 silver badges14 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 4

This doesn't work because guards are not registered as providers in a module. They get directly instantiated by the framework.

You can either use dependency injection in the guard:

@Injectable()
export class MyAuthGuard {
  constructor(private readonly configService: ConfigService) {
    // use the configService here
  }
}

and

@UseGuards(MyAuthGuard)

or instantiate the guard yourself:

@UseGuards(new AuthGuard(configService.get('some_key')))

In the special case of the AuthGuard, you can set a defaultStrategy in the PassportModule. Then you can just use @UseGuards(AuthGuard())

PassportModule.register({ defaultStrategy: 'jwt'}) 

or async:

PassportModule.registerAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({ defaultStrategy: configService.authStrategy}),
  inject: [ConfigService],
}) 

Let's say you want your specific guard instance to perform differently depending on some input, basically be able to configure it. There is no option to consume this config from constructor(). Factory way might look like a bit bulky solution. But you're still able to utilise static methods to achieve wanted behaviour.

Example:

@Injectable()
class SomeController {
  @Get()
  @UseGuard(AuthGuard) // but how to pass smth inside AuthGuard?
  public async doSomething() {}
}

Solution:

// [auth.guard.ts] file
import { UnauthorizedException, Injectable } from '@nestjs/mon';
import type { CanActivate, ExecutionContext } from '@nestjs/mon';
import type { GuardOptions, PatchedRequest } from './auth.types';


export interface GuardOptions {
  allowAnonymous?: boolean,
  allowExpired?: boolean,
}

@Injectable()
export class AuthGuard
implements CanActivate {
  public options: GuardOptions = {};
  public canActivate(
    context: ExecutionContext,
  ): boolean | Promise<boolean> {
    // Guard logic 
    return true;
  }

  static configure(options: GuardOptions) {
    const instance = new AuthGuard;
    instance.options = options;
    return instance;
  }
}


// [someEntity.controller.ts] file
// imports...

@Injectable()
class SomeController {
  @Get()
  @UseGuard(AuthGuard.configure({ allowExpired: true })) // voila
  public async doSomething() {}
}

Enjoy! Glory to Ukraine!

I would try ht less verbose approach and inject ConfigService directly into the AuthGuard in such a manner:

@Module({
  imports: [
    CoreModule,
  ],
  providers: [
    AuthGuard,
  ],
  exports: [
    AuthGuard,
  ],
})
@Injectable()
export default class AuthGuard {
  constructor (protected readonly config: ConfigService) {
  }
  /*
  ...
  */
}
发布评论

评论列表(0)

  1. 暂无评论