0

I specify guards for JWT and SSO in my Nest.js api, but now that the project gets larger some specific resolvers need to be accesable by both auth strategies.

I've created a ChainGuard which loops through the guards:

@Injectable()
export class ChainGuard extends AuthGuard(['jwt', 'sso']) {...}

Now I want to use it in one of my resolvers as this:

import { Controller, Get, UseGuards } from '@nestjs/common';
import { JWTGuard } from './jwt.guard';
import { ChainGuard } from './chain.guard';

@Controller('users')
@UseGuards(JWTGuard)
export class UsersController {
  @Get()
  getUsers() {
    // Return list of users
  }

  @Get(':id')
  @UseGuards(ChainGuard)
  getUser(@Param('id') id: string) {
    // Return user details for the given ID
  }
}

This doesn't seem to work as I can't bypass the class guard JWTGuard

After researching a bit, most people recommend setting metadata for that specific resolver if you are trying to bypass the WHOLE authentication (e.g. public endpoint). But I'm not trying to do that, I just want to use a different guard while keeping the same old guard for the other resolvers in that Class.

Is something like this possible?

ekclone
  • 1,030
  • 2
  • 17
  • 39

1 Answers1

0

I would still end up creating a metadata that is specific to the JWTGuard, where JWTGuard extends AuthGuard('jwt'). That way, you can skip that guard, and still make use of AuthGuard(['jwt', 'sso']) (i.e. ChainGuard) without worry of that metadata being read, because ChainGuard doesn't have the logic for that. Something like

export const SkipJwtGuard = () => SetMetadata('SKIP_JWT_GUARD', true)

And in your JWTGuard you can use this.reflector.get('SKIP_JWT_GUARD', context.getHandler()) and if that returns true then you can short circuit this guard.

Jay McDoniel
  • 57,339
  • 7
  • 135
  • 147