Voici mon point de vue sur ce sujet et une solution possible pour le problème du fournisseur manquant.
Dans mon cas, nous avons un garde qui prend une permission ou une liste de permissions en paramètre, mais c'est la même chose que d'avoir un rôle.
Nous avons une classe pour gérer les gardes d'authentification avec ou sans permission :
@Injectable()
export class AuthGuardService implements CanActivate {
checkUserLoggedIn() { ... }
Cela concerne la vérification de la session active de l'utilisateur, etc.
Il contient également une méthode utilisée pour obtenir un garde de permission personnalisé, qui dépend en réalité de la classe AuthGuardService
elle-même.
static forPermissions(permissions: string | string[]) {
@Injectable()
class AuthGuardServiceWithPermissions {
constructor(private authGuardService: AuthGuardService) { } // utilise en fait l'instance de la classe parent, mais pourrait en théorie prendre tout autre dépendance
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
// vérifie l'activation typique (auth) + les permissions personnalisées
return this.authGuardService.canActivate(route, state) && this.checkPermissions();
}
checkPermissions() {
const user = ... // obtenir l'utilisateur actuel
// vérifie les permissions données avec l'utilisateur actuel
return user.hasPermissions(permissions);
}
}
AuthGuardService.guards.push(AuthGuardServiceWithPermissions);
return AuthGuardServiceWithPermissions;
}
Cela nous permet d'utiliser la méthode pour enregistrer certains gardes personnalisés basés sur le paramètre de permissions dans notre module de routage :
....
{ path: 'quelquechose',
component: SomeComponent,
canActivate: [ AuthGuardService.forPermissions('permission1', 'permission2') ] },
La partie intéressante de forPermission
est AuthGuardService.guards.push
- cela garantit essentiellement qu'à chaque fois que forPermissions
est appelé pour obtenir une classe de garde personnalisée, elle sera également stockée dans ce tableau. Cela est également statique sur la classe principale :
public static guards = [ ];
Ensuite, nous pouvons utiliser ce tableau pour enregistrer tous les gardes - c'est bien tant que nous nous assurons que lorsque le module de l'application enregistre ces fournisseurs, les routes ont été définies et que toutes les classes de garde ont été créées (par exemple, vérifiez l'ordre d'importation et gardez ces fournisseurs aussi bas que possible dans la liste - avoir un module de routage aide) :
providers: [
// ...
AuthGuardService,
...AuthGuardService.guards,
]
En espérant que cela vous aidera.