0

I'm trying to authorize users based on their permissions. Is there any difference in functionality between using createParamDecorator and CanActivate method?

export const GetUser = createParamDecorator((data: string, ctx: ExecutionContext) : User => {

  const request = ctx.switchToHttp().getRequest();
  const user  = request.user;
  const permissions = user.permissions
  for(var i = 0; i < permissions.length; i++){
      if(permissions[i].name === data)
         return user;
  }
  throw new NotFoundException()})
sinister
  • 3
  • 2
  • I don't think they aren't equivalent at all. With `createParamDecorator` you creates a decorator factory. With nestjs's guards you define whether or not an icoming request should go further – Micael Levi May 28 '21 at 20:49
  • With the custom decorator, It's possible to access req and user and also permissions. so you can authorize user based on permissions via createParamDecorator. – sinister May 28 '21 at 21:16
  • You're right but I've never see this approach. Could you please show us an example of using `createParamDecorator` for this? – Micael Levi May 28 '21 at 21:37
  • I edited the post. – sinister May 28 '21 at 21:47

1 Answers1

1

These are absolutely not equivalent approaches, and should not be considered as such. The createParamDecorator is supposed to be an easy way to tell Nest how to inject a custom value (e.g. req.user instead of having to do @Req() { user }). It was never meant to be used for authorization, and while you can, it will most likely lead to very weird stack traces.

Guards, on the other hands, were made for authentication and authorization of the request. You can set metadata on a handler (e.g. what roles are allowed), read them with the Reflector, and then apply the conditional logic of if the request is valid or not. You're also able to use dependency injection on guards to add things like your database connection and get a full user from the database from an ID, which isn't possible in the createParamDecorator.

Lastly, in guards you can throw any error you want, or you can return false and get back a 403 by Nest's design.

Is there any difference in functionality...?

As mentioned, the dependency injection. It's also easier to test guards, in my opinion. But that's me.

Jay McDoniel
  • 57,339
  • 7
  • 135
  • 147
  • Thanks for your response. In createParamDecorator you can also throw whatever you want, but what do you mean by weird stack traces? – sinister May 29 '21 at 06:55