Estou trabalhando em um aplicativo que tem várias funções e preciso usar guardas para bloquear a navegação em partes do aplicativo com base nessas funções. Sei que posso criar classes de guarda individuais para cada função, mas preferiria ter uma classe para a qual pudesse de alguma forma passar um parâmetro. Em outras palavras, gostaria de ser capaz de fazer algo semelhante a isto:
{
path: 'super-user-stuff',
component: SuperUserStuffComponent,
canActivate: [RoleGuard.forRole('superUser')]
}
Mas, como tudo que você passa é o nome do tipo do seu guarda, não consigo pensar em uma maneira de fazer isso. Devo apenas controlar a bala e escrever as classes de guarda individuais por função e destruir minha ilusão de elegância em ter um único tipo parametrizado?
angular
typescript
angular2-routing
Brian Noyes
fonte
fonte
roles
objeto e o protetor de rota estão vinculados sem saber com antecedência como o código funciona. É uma pena que o Angular não ofereça suporte a uma maneira de fazer isso de forma mais declarativa. (Para ficar claro, sou eu lamentando o Angular, não essa solução perfeitamente razoável.)Aqui está minha opinião sobre isso e uma possível solução para o problema do provedor ausente.
No meu caso, temos um guarda que leva uma permissão ou lista de permissões como parâmetro, mas é a mesma coisa ter uma função.
Temos uma aula para lidar com os guardas de autenticação com ou sem permissão:
Trata-se de verificar a sessão ativa do usuário, etc.
Ele também contém um método usado para obter uma proteção de permissão personalizada, que na verdade depende do
AuthGuardService
próprioIsso nos permite usar o método para registrar alguns guardas personalizados com base no parâmetro de permissões em nosso módulo de roteamento:
A parte interessante disso
forPermission
éAuthGuardService.guards.push
- basicamente, isso garante que a qualquer momento queforPermissions
for chamado para obter uma classe de guarda personalizada, ela também a armazenará neste array. Isso também é estático na classe principal:Então, podemos usar essa matriz para registrar todos os guardas - isso está ok, contanto que tenhamos certeza de que, no momento em que o módulo de app registra esses provedores, as rotas foram definidas e todas as classes de guarda foram criadas (por exemplo, verificar a ordem de importação e mantenha esses provedores o mais baixo possível na lista - ter um módulo de roteamento ajuda):
Espero que isto ajude.
fonte
ERROR in Error during template compile of 'RoutingModule' Function calls are not supported in decorators but 'PermGuardService' was called.
A solução de @AluanHaddad está apresentando o erro "nenhum provedor". Aqui está uma solução para isso (parece sujo, mas não tenho as habilidades para fazer um melhor).
Conceitualmente, eu registro, como um provedor, cada classe gerada dinamicamente criada por
roleGuard
.Portanto, para cada função verificada:
Você devia ter:
No entanto, a solução no estado em que se encontra de @AluanHaddad gerará uma nova classe para cada chamada a
roleGuard
, mesmo se oroles
parâmetro for o mesmo. Usandolodash.memoize
a aparência:Observe que cada combinação de funções gera uma nova classe, então você precisa se registrar como um provedor cada combinação de funções. Ou seja, se você tem:
canActivate: [roleGuard('foo')]
ecanActivate: [roleGuard('foo', 'bar')]
você terá que registrar ambos:providers[roleGuard('foo'), roleGuard('foo', 'bar')]
Uma solução melhor seria registrar provedores automaticamente em uma coleção global de provedores internos
roleGuard
, mas como eu disse, não tenho as habilidades para implementar isso.fonte