Nest JS Guards – Use one of two strategies

My app has two JWT based strategies:

  • Single sign on for my organization and its members. An external provider creates a JWT for this case.
  • Email/Password authenticated external users. My app creates a JWT for this case.

On any given route, I only need one of these to succeed to allow access. The problem is that if multiple guards are declared, then ALL guards must succeed.

For example, this would require both guards to succeed, but only one will ever succeed.

@UseGuards(AuthGuard('local-jwt'))
@UseGuards(AuthGuard('azure-ad'))
someRoute(
  @CurrentUser currentUser: User,
) {
  //...
}

On this issue, I found this snippet:

@Injectable()
export class ComposeGuard implements CanActivate {
  constructor(private allowGuard: AllowGuard, private authGuard: AuthGuard, private roleGuard: RoleGuard) {
  }

  async canActivate(context: ExecutionContext): Promise<boolean> {
    return await this.allowGuard.canActivate(context) || (await this.authGuard.canActivate(context) &&  await this.roleGuard.canActivate(context));
  }
}

This seems to allow the custom logic I need, but I have no idea how to import the guards as dependencies. A guard does not seem to be a class, so it’s valid for dependency injection. And a strategy is a class, but does not have a canActivate method.


The other option I found was to make one strategy inherit from the other. But that’s an ugly semantic mess since they are parallel, and do not depend on one another at all.

88 thoughts on “Nest JS Guards – Use one of two strategies”

Leave a Comment