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()})
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 thecreateParamDecorator
.Lastly, in guards you can throw any error you want, or you can return
false
and get back a 403 by Nest's design.As mentioned, the dependency injection. It's also easier to test guards, in my opinion. But that's me.