Pesquisa de site

javascript - Nest JS Guards - Usar uma de duas estratégias


Meu aplicativo possui duas estratégias baseadas em JWT:

  • Login único para a minha organização e seus membros. Um provedor externo cria um JWT para este caso.
  • Usuários externos autenticados por E-mail/Senha. Meu aplicativo cria um JWT para este caso.

Em qualquer rota, eu só preciso que um deles tenha sucesso para permitir o acesso. O problema é que, se vários guardas forem declarados, então TODOS os guardas devem ter sucesso.

Por exemplo, isso exigiria que ambos os guardas tivessem sucesso, mas apenas um deles terá sucesso.

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

Sobre este assunto, encontrei este trecho:

@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));
  }
}

Isso parece permitir a lógica personalizada que eu preciso, mas eu não tenho ideia de como importar os guards como dependências. Um guard não parece ser uma classe, então é válido para injeção de dependência. E uma estratégia é uma classe, mas não possui um método canActivate.


A outra opção que encontrei foi fazer uma estratégia herdar da outra. Mas isso é uma bagunça semântica feia, já que elas são paralelas e não dependem uma da outra de forma alguma.

Resposta #1

De acordo com este pull request, você pode usar @UseGuards(AuthGuard(['strategy1', 'strategy2'])). O Passport executará a primeira estratégia; se falhar, ele passará para a strategy2, até strategyN. Se houver um erro ao executar a estratégia, ele falhará rapidamente.

Artigos relacionados