0

I have a controller which has an authentication guard and a RBAC authorization guard

@Get('get-framework-lists')
@UseGuards(JwtAuthGuard) // authentication guard
@Roles(Role.SO) // RBAC authorization guard
getFrameworkListsByCompany() {
  return this.dashboardService.getFrameworkListsByCompany();
}

JwtAuthGuard look like this -

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor(@InjectModel(User.name) private userModel: Model<UserDocument>) {
    super({
      ignoreExpiration: false,
      secretOrKey: 'SECRET',
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
    });
  }

  async validate(payload: any) {
    const user = await this.userModel.findById(payload.sub);
    return {
      _id: payload.sub,
      name: payload.name,
      ...user,
    };
  }
}

I have created a custom Roles.guard.ts for @Roles decorator

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

  canActivate(context: ExecutionContext): boolean {
    const requiredRole = this.reflector.getAllAndOverride<Role>(ROLES_KEY, [
      context.getHandler(),
      context.getClass(),
    ]);

    if (!requiredRole) {
      return true;
    }

    console.log({ requiredRole });

    const { user } = context.switchToHttp().getRequest();

     return requiredRole === user.role;
    
  }
}

In the controller, I can access req.user as user is added to the request object. However, I am not getting the user as undefined in roles.guard.ts.

What am I doing wrong here?

vaibhav deep
  • 655
  • 1
  • 8
  • 27

1 Answers1

2

I think that simple add RolesGuard inside the @UseGuards() decorator, so that both guards can run, will solve your problem.
Like this:

@Get('get-framework-lists')
@UseGuards(JwtAuthGuard, RolesGuard) // here is the change
@Roles(Role.SO)
getFrameworkListsByCompany() {
  return this.dashboardService.getFrameworkListsByCompany();
}

air_ioannis
  • 146
  • 1
  • 6