jmcdo29 / nest-lab

A repository to hold "experimental" packages for Nest. Honestly, I'm just tired of not having a good scope to put packages under :smile_cat:
87 stars 7 forks source link

Issue with AndGuard guards execution order #35

Closed its-monotype closed 9 months ago

its-monotype commented 10 months ago

I have a problem when using AndGuard with JwtAuthGuard from passport.js and RolesGuard.

In JwtAuthGuard user fetched in DB (inside jwt passport strategy) and returned, this will attach it to the request.

and inside RolesGuard I'm extracting the user from context.switchToHttp().getRequest()

but I receive undefined when using AndGuard, btw without it everything works fine, I assume that JwtAuthGuard must be executed before RolesGuard so it will attach the user to req before so RolesGuard can grab it

its-monotype commented 10 months ago

Btw this custom solution works fine:

@Injectable()
export class JwtAuthRolesCompositeGuard implements CanActivate {
  constructor(
    private jwtAuthGuard: JwtAuthGuard,
    private rolesGuard: RolesGuard,
  ) {}

  async canActivate(context: ExecutionContext): Promise<boolean> {
    const hasJwtAuthAccess = await this.jwtAuthGuard.canActivate(context);
    const hasRolesAccess = await this.rolesGuard.canActivate(context);

    if (hasJwtAuthAccess && hasRolesAccess) {
      return true;
    }

    return false;
  }
}
jmcdo29 commented 10 months ago

Please provide a minimum reproduction repository (Git repository/StackBlitz/CodeSandbox project).

why reproductions are required

its-monotype commented 10 months ago

@jmcdo29 Here you go https://github.com/its-monotype/nest-and-guard

Steps to reproduce:

  1. Clone repo.
  2. Install and start the app.
  3. Try running:
    curl -X POST http://localhost:3000/admin/and-guard -d '{"username": "john", "password": "changeme"}' -H "Content-Type: 
    application/json"
  4. Observe {"message":"Forbidden resource","error":"Forbidden","statusCode":403}

If you will try to do the same but with endpoint that not uses AndGuard it works fine, try running:

curl -X POST http://localhost:3000/admin -d '{"username": "john", "password": "changeme"}' -H "Content-Type: application/json"

Please, take a look at app.controller.ts

jmcdo29 commented 10 months ago

Ah, okay, yep I see. So the AndGuard, at the moment, is designed to not care about the order of execution of the guards it's told about. That's to make it as quick as possible. However, I can certainly see situations where you want it to be order dependent. Maybe I can add a new option that dictates the guards should be ran sequentially instead of in parallel

jmcdo29 commented 9 months ago

Should be available in @nest-lab/or-guard@2.4.0

its-monotype commented 9 months ago

Should be available in @nest-lab/or-guard@2.4.0

Wow, that was fast! I'll try it soon and let you know how it goes. Thanks for considering my request! 😃

its-monotype commented 9 months ago

Works perfectly, thanks again