Ecco la mia opinione su questo e una possibile soluzione per il problema del provider mancante.
Nel mio caso, abbiamo una guardia che prende un permesso o un elenco di permessi come parametro, ma è la stessa cosa che ha un ruolo.
Abbiamo una classe per trattare con le guardie di autenticazione con o senza autorizzazione:
@Injectable()
export class AuthGuardService implements CanActivate {
checkUserLoggedIn() { ... }
Si occupa del controllo della sessione attiva dell'utente, ecc.
Contiene anche un metodo utilizzato per ottenere una protezione di autorizzazione personalizzata, che in realtà dipende da AuthGuardService
essa stessa
static forPermissions(permissions: string | string[]) {
@Injectable()
class AuthGuardServiceWithPermissions {
constructor(private authGuardService: AuthGuardService) { } // uses the parent class instance actually, but could in theory take any other deps
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
// checks typical activation (auth) + custom permissions
return this.authGuardService.canActivate(route, state) && this.checkPermissions();
}
checkPermissions() {
const user = ... // get the current user
// checks the given permissions with the current user
return user.hasPermissions(permissions);
}
}
AuthGuardService.guards.push(AuthGuardServiceWithPermissions);
return AuthGuardServiceWithPermissions;
}
Questo ci consente di utilizzare il metodo per registrare alcune guardie personalizzate in base al parametro delle autorizzazioni nel nostro modulo di instradamento:
....
{ path: 'something',
component: SomeComponent,
canActivate: [ AuthGuardService.forPermissions('permission1', 'permission2') ] },
La parte interessante di forPermission
è che AuthGuardService.guards.push
questo fondamentalmente assicura che ogni volta che forPermissions
viene chiamato per ottenere una classe di guardia personalizzata, la memorizzerà anche in questo array. Anche questo è statico nella classe principale:
public static guards = [ ];
Quindi possiamo usare questo array per registrare tutte le guardie - questo va bene fintanto che ci assicuriamo che nel momento in cui il modulo dell'app registra questi provider, le rotte siano state definite e tutte le classi di guardia siano state create (es. Controllare l'ordine di importazione e mantenere questi provider il più basso possibile nell'elenco - avere un modulo di routing aiuta):
providers: [
// ...
AuthGuardService,
...AuthGuardService.guards,
]
Spero che questo ti aiuti.