LeSchwambo
LeSchwambo

Reputation: 754

NestJS 01-cats-app: When trying a post request I get a 403 error

I am trying to understand NestJS 01-cats-app. When trying a post request, I get a 403 error. I know that is due to the @Roles('admin')decorator. But how do I create a post request as an admin? I use postman btw.

Here is the example: https://github.com/nestjs/nest/tree/master/sample/01-cats-app

enter image description here enter image description here

Upvotes: 1

Views: 2773

Answers (1)

Ferin Patel
Ferin Patel

Reputation: 3968

Here, roles are being validated by Guards. So in this case, 'admin' role will be validated inside guards file.

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';

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

  canActivate(context: ExecutionContext): boolean {
    const roles = this.reflector.get<string[]>('roles', context.getHandler());
    if (!roles) {
      return true;
    }
    const request = context.switchToHttp().getRequest();
    const user = request.user;
    return matchRoles(roles, user.roles);
  }
}

In the above code, raw request is extracted from context and it has user object inside it which contains roles.

However, we need to inject user object into request using middleware or something like that.

For more information, you can read official docs for guards from nestjs

https://docs.nestjs.com/guards

JWT based auth sample

async canActivate(context: ExecutionContext): Promise<boolean> {
    const request = context.switchToHttp().getRequest() as Request & {
      user: User;
    };

    const authorization = request.headers.authorization || '';

    if (!authorization.trim().length) {
      throw new UnauthorizedException();
    }

    const token = authorization.split(' ')[1];

    if (!token) {
      throw new UnauthorizedException();
    }

    let decoded: PayloadType | null = null;
    try {
      decoded = verify(
        token,
        process.env.ACCESS_SECRET || 'qwertyuiop',
      ) as PayloadType;
    } catch (error) {
      throw new BadRequestException(error.message);
    }

    const role = this.reflector.get<string[]>('roles', context.getHandler());
    if (!role) {
      return true;
    }

    const user = (await User.findOne(decoded.id, {
      select: [
        'tokenVersion',
        'id',
        'email',
        'isPaidUser',
        'firstName',
        'lastName',
        'profileUrl',
        'roles',
      ],
    })) as User;
    if (!user) {
      throw new NotFoundException('user not found');
    }
   
    if (user.tokenVersion !== decoded.tokenVersion) {
      throw new BadRequestException('token invalid');
    }

     const hasRole = () =>
      user.roles.some(role => !!roles.find(item => item === role));

     if(!hasRole){
      throw new UnauthorizedException();
   }

    request.user = serializeUser(user);
    return true;
  }

Upvotes: 1

Related Questions