Skip to main content

Angular CanActivate vs. Interceptors

  • Angular CanActivate vs. Interceptors

Angular CanActivate vs. Interceptors - Um Guia Abrangente

Como escolher entre eles para obter exatamente o que deseja

https://miro.medium.com/max/700/1*QN4mRDGHkBlZUvdYHNxePA.jpeg

CanActivate e interceptores são ótimas ferramentas para manipular e configurar padrões de autenticação. Mas eles são muitas vezes incompreendidos porque parecem representar mecanismos semelhantes enquanto são muito diferentes uns dos outros.

A única coisa em comum entre essas duas ferramentas é que ambas são classes implementando interfaces Angular e ambas as interfaces requerem um único método para serem implementadas. É muito simples codificá-los. Mas como não há um padrão de design comum para usar com essas classes, pode ser difícil escolher qual usar ou preferir em relação à outra.

A interface CanActivate

https://miro.medium.com/max/700/1*cgJAj4z-SXT06DnHkrEcyA.jpeg

Essa interface requer que a classe implemente o canActivate()método, cujos parâmetros são a rota atual e o estado.

O principal objetivo desta interface é produzir um booleano indicando se a rota atual é acessível ou não pela navegação.

O importante sobre essa interface é que o valor retornado pode ser um booleano simples, um Promise<boolean>ou um Observable<boolean>. Isso torna a classe que implementa a interface muito mais versátil, pois podemos produzir um booleano em um determinado ponto, mesmo que não imediatamente. Em vez de responder diretamente ao Angular Router, podemos autenticar a invocação de URL usando um serviço web. Então temos dois padrões comuns para a implementação:

  1. Síncrono

    : Verifica se o usuário atual tem privilégios para acessar a rota, usando um sistema RBAC (Role-Based Access Control) ou simplesmente verificando se o token de autenticação está armazenado corretamente onde deveria estar e se não expirou

  2. Assíncrono

    : Verifica via AJAX se o usuário pode acessar o roteador, novamente usando controles do lado do servidor RBAC ou validando o token e seu resumo para verificar se não foi hackeado ou stub com algo errado

No caso síncrono, lembre-se de que você precisa emitir um Observable<boolean>usando operadores Rx como pipe()map()catchError()e construtores Observable como of().

A Interface HttpInterceptor

https://miro.medium.com/max/700/1*3lzjuR13ftNQaVgVP8kkcg.png

Esta interface requer a implementação do intercept()método. Os interceptores angulares são semelhantes ao middleware (como o middleware do Express, por exemplo), interceptando e trabalhando em todas as solicitações HTTP. Os interceptores são frequentemente usados para anexar cabeçalhos HTTP a solicitações, lê-los ou filtrá-los. Um interceptor Angular funciona em todas as solicitações HTTP e não pode interceptar apenas parte delas, a menos que você codifique e alterne cada URL HTTP, definindo regras para isso.

Os interceptores trabalham em todas as solicitações, manipulando ou lendo dados deles. Em um aplicativo de página única, eles basicamente funcionam em solicitações AJAX porque não usamos um padrão de navegação do lado do servidor.

O método de interface recebe dois parâmetros: o primeiro para inspecionar a solicitação atual e o segundo para encaminhá-la na cadeia e fazer com que o processo HTTP continue. Observe que o Angular HttpRequestnão pode ser modificado diretamente, mas deve ser clonado e encaminhado conforme descrito na documentação oficial .

Implementação angular

Existem duas maneiras separadas de usar interceptores e CanActivates dentro de um aplicativo Angular. Cada classe que implementa essas interfaces deve ser incluída e declarada no app.module.tsou dentro de seu módulo personalizado para funcionar.

Como eles são diferentes um do outro, sua inclusão no módulo é um pouco diferente. Ambos os interceptores e CanActivates (às vezes chamados de guards ) devem ser declarados dentro do array do provedor. Mas enquanto os guardas só precisam ser incluídos, os interceptores precisam de uma declaração um pouco mais complicada:

// app.module.tsprovedores: [
MyService,
MyOtherService,
...,
AuthGuard, // <- implementa canActivate
RoleGuard, // <- implementa canActivate
...,
// Interceptor
{
provide : HTTP_INTERCEPTORS,
useClass : TokenInterceptor,
multi : true
}
],
/ / continuo...
],

Como você pode ver, CanActivates é simplesmente incluído, mas os interceptores precisam ser declarados dentro de um objeto especial com estes campos:

provide: um token multi-provedor usado para injetar o interceptor

useClass: representando a classe atual do interceptor

multi: descreve se HTTP_INTERCEPTORSé um token para um multiProviderque injeta uma matriz de valores em vez de um único valor

Conclusões e principais diferenças

Tanto os CanActivates (guardas) quanto os interceptores podem ser usados para bloquear a navegação em uma rota ou para implementar mecanismos de autorização. No entanto, eles são bem diferentes e devem ser usados separadamente em diferentes contextos.

  • CanActivates funciona em rotas únicas, as interfaces funcionam em todas as solicitações HTTP

    . Isso significa que, se você precisar manipular o HTTP em sua totalidade, precisará de um interceptor. Se você precisa ter controle sobre uma rota, deve usar um guarda.

  • CanActivates pode ser assíncrono, enquanto os interceptores não podem

    . Não faz sentido ter um interceptor fazendo as coisas de forma assíncrona e, em seguida, usar um guarda para autenticar seu token ou conceder acesso via AJAX.

  • CanActivates são feitos para serem encadeados

    . É raro precisar de vários interceptadores, enquanto os guardas geralmente são acorrentados um ao outro. Isso permite que vários guardas analisem o acesso a uma rota especificada e evitem ou concedam acesso.

A implementação e o padrão de guardas e interceptores de código são muito dependentes do contexto do aplicativo, pois aplicativos diferentes exigem mecanismos de autenticação diferentes e específicos. Alguns aplicativos precisam que uma página de login seja exibida quando são iniciados. Outros exigem que o usuário esteja logado em pontos-chave específicos, assim como um CRM (totalmente bloqueado) e um aplicativo da web de comércio eletrônico, que pode solicitar que o usuário faça login apenas durante o checkout.

Usar guardas e interceptores é fácil, mas você precisa praticar alguns padrões para evitar sobrecarga de computação e entender se precisa de um ou de outro.