Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to provide a Guard for a specific Module in Nest.js?

Tags:

nestjs

I have a module called AdminModule which should be protected by AdminGuard.

I tried to set up the Guard directly in the module like this:

@Module({
  imports: [
    HttpModule,
  ],
  controllers: [AdminController],
  providers: [
    {
      provide: APP_GUARD,
      useClass: AdminGuard,
    },
    AdminService,
  ],
})
export class AdminModule {
}

However, the guard is not limited to this module but it is global (as stated in the docs: "the guard is, in fact, global").

But how is it possible to make the guard only protect a module?

like image 351
Maurice Wipf Avatar asked May 31 '19 15:05

Maurice Wipf


People also ask

What is a guard in NestJS?

A guard is a class annotated with the @Injectable() decorator, which implements the CanActivate interface. Guards have a single responsibility.

What is canActivate in NestJS?

What is canActivate in NestJS? Every guard must implement a canActivate() function. This function should return a boolean, indicating whether the current request is allowed or not. It can return the response either synchronously or asynchronously (via a Promise or Observable ).

What is reflector in NestJS?

The Reflector#get method allows us to easily access the metadata by passing in two arguments: a metadata key and a context (decorator target) to retrieve the metadata from. In this example, the specified key is 'roles' (refer back to the roles.

What is passport in NestJS?

Passport is the most popular node.js authentication library, well-known by the community and successfully used in many production applications. It's straightforward to integrate this library with a Nest application using the @nestjs/passport module.


1 Answers

Update : there is actually no options to achieve that.

Information :

What you've done by using APP_GUARD is to apply it globally. It's the same as using useGlobalGuards, but this way allows you to take advantage of the DI system.

{
  provide: APP_GUARD,
  useClass: AdminGuard,
},

If you don't want to apply it globally, don't add this to the provider's array in the module.

Instead, just create a new guard like this

@Injectable()
export class RolesGuard implements CanActivate {
  canActivate(
    context: ExecutionContext,
  ): boolean | Promise<boolean> | Observable<boolean> {
    return true;
  }
}

See the documentation here: https://docs.nestjs.com/guards

And then apply it on your controller at the class level to impact all the handlers of the controller, or to a method to impact a specific endpoint.

@UseGuards(RolesGuard)
like image 167
Adrien De Peretti Avatar answered Oct 07 '22 20:10

Adrien De Peretti