Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to pass a parameter to a nestjs guard?

Tags:

nestjs

I'm trying to come up with a somewhat reusable guard and it looks like I need to pass a string param to a guard. Is it achievable in nestjs?

like image 334
Albert Avatar asked May 27 '20 15:05

Albert


People also ask

When to pass arguments to nestjs interceptors and guards?

We use NestJs interceptors and guards daily, and most often we do not need to wrap them into factories, but every once in a while we need to pass an argument statically to them when we decorate some controller or some controller’s method. Let’s say that we need to send some metrics, KPI, to track usage of our app.

Is it possible to pass data from a guard to controller?

So that means there most be @Body on event function that would need this form of Authoriztion. The only ways possible to pass data from a Guard to a Controller is to either attach the data to a field on the request or to use some sort of metadata reflection, which may become more challenging than it is worth.

How do I validate the correctness of data sent into nest?

It is best practice to validate the correctness of any data sent into a web application. To automatically validate incoming requests, Nest provides several pipes available right out-of-the-box: The ValidationPipe makes use of the powerful class-validator package and its declarative validation decorators.

What is the use of guard in a controller request?

The guard is there to return true or false (or an async variant of it) so that the system knows whether or not to continue the request or return an error code. > And in your controller you could then pull req.myData ...


2 Answers

It sounds like you are looking to use a mixin, a function that returns a class. I'm not sure what kind of parameter you're passing, but the idea is

export const RoleGuard = (role: string) => {
  class RoleGuardMixin implements CanActivate {
    canActivate(context: ExecutionContext) {
      // do something with context and role
      return true;
    }
  }

  const guard = mixin(RoleGuardMixin);
  return guard;
}

mixin as a function is imported from @nestjs/common and is a wrapper function that applies the @Injectable() decorator to the class

Now to use the guard, you need to do something like @UseGuards(RoleGuard('admin'))

like image 126
Jay McDoniel Avatar answered Oct 25 '22 18:10

Jay McDoniel


It seems impossible to use mixin in Guard in NestJs. It will throw Exported variable 'RoleGuard' has or is using private name 'RoleGuardMixin'.

Actually, you may use setMetadata to pass in the parameters one by one, then get it from the Guard using reflector from from '@nestjs/core'.

    @Injectable()
    export class RoleGuard implements CanActivate {
        constructor(
            private reflector: Reflector,
        ) {}

        canActivate(context: ExecutionContext) {
          const roleName = this.reflector.get<string>('roleName', context.getHandler());
          return true;
        }
    }
    @Get()
    @SetMetadata('roleName', 'developer')
    async testRoleGuard() {
      return true;
    }

Or you may define a decorator to pass the parameter in.

export const RoleName = (roleName: string) => SetMetadata('roleName', roleName);
    @Get()
    @RoleName('developer')
    async testRoleGuard() {
      return true;
    }
like image 25
Jeffrey Chu Avatar answered Oct 25 '22 17:10

Jeffrey Chu