Esta es mi opinión sobre esto y una posible solución para el problema del proveedor que falta.
En mi caso, tenemos un guardia que toma un permiso o lista de permisos como parámetro, pero es lo mismo que tiene un rol.
Tenemos una clase para tratar con los guardias de autenticación con o sin permiso:
@Injectable()
export class AuthGuardService implements CanActivate {
checkUserLoggedIn() { ... }
Se trata de comprobar la sesión activa del usuario, etc.
También contiene un método que se utiliza para obtener un protector de permisos personalizado, que en realidad depende del AuthGuardService
propio
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;
}
Esto nos permite usar el método para registrar algunos guardias personalizados basados en el parámetro de permisos en nuestro módulo de enrutamiento:
....
{ path: 'something',
component: SomeComponent,
canActivate: [ AuthGuardService.forPermissions('permission1', 'permission2') ] },
La parte interesante de forPermission
es AuthGuardService.guards.push
- esto básicamente se asegura de que cada vez que forPermissions
se llama para obtener una clase de protección a medida que también lo almacenará en esta matriz. Esto también es estático en la clase principal:
public static guards = [ ];
Luego, podemos usar esta matriz para registrar todos los guardias; esto está bien siempre y cuando nos aseguremos de que para cuando el módulo de la aplicación registre a estos proveedores, las rutas se hayan definido y todas las clases de guardias se hayan creado (por ejemplo, verificar el orden de importación y mantenga estos proveedores lo más bajo posible en la lista; tener un módulo de enrutamiento ayuda):
providers: [
// ...
AuthGuardService,
...AuthGuardService.guards,
]
Espero que esto ayude.