Oto moje podejście do tego i możliwe rozwiązanie problemu z brakującym dostawcą.
W moim przypadku mamy strażnika, który jako parametr przyjmuje pozwolenie lub listę uprawnień, ale to samo ma rolę.
Mamy klasę do radzenia sobie ze strażnikami auth z pozwoleniem lub bez:
@Injectable()
export class AuthGuardService implements CanActivate {
checkUserLoggedIn() { ... }
Dotyczy to sprawdzania aktywnej sesji użytkownika itp.
Zawiera również metodę używaną do uzyskiwania niestandardowej ochrony uprawnień, która w rzeczywistości zależy od AuthGuardService
siebie
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;
}
To pozwala nam użyć metody do zarejestrowania niektórych niestandardowych strażników na podstawie parametru permissions w naszym module routingu:
....
{ path: 'something',
component: SomeComponent,
canActivate: [ AuthGuardService.forPermissions('permission1', 'permission2') ] },
Interesującą częścią forPermission
jest AuthGuardService.guards.push
to, że w zasadzie zapewnia to, że za każdym razem, gdy forPermissions
zostanie wywołana w celu uzyskania niestandardowej klasy ochrony, będzie ona również przechowywać ją w tej tablicy. Jest to również statyczne w głównej klasie:
public static guards = [ ];
Następnie możemy użyć tej tablicy do zarejestrowania wszystkich strażników - jest to w porządku, o ile upewnimy się, że zanim moduł aplikacji zarejestruje tych dostawców, trasy zostały zdefiniowane i wszystkie klasy ochrony zostały utworzone (np. Sprawdź kolejność importu i utrzymuj tych dostawców jak najniżej na liście - posiadanie modułu routingu pomaga):
providers: [
// ...
AuthGuardService,
...AuthGuardService.guards,
]
Mam nadzieję że to pomoże.