Agradeceríamos tu ayuda para compartir nuestras crónicas en referencia a las ciencias de la computación.
Solución:
Elegí un camino diferente: anidar a mis guardias y convertirlos en dependencias entre sí.
tengo un RequireAuthenticationGuard
y un RequirePermissionGuard
. Para la mayoría de las rutas, ambos deben ejecutarse, pero hay un orden específico que necesito.
El RequireAuthenticationGuard
depende de mis servicios de autenticación para comprobar si la sesión actual está autenticada.
El RequirePermissionGuard
depende de mis servicios de autenticación para comprobar si la sesión actual está autorizada para una ruta.
Agrego el RequireAuthenticationGuard
como una dependencia del constructor de RequirePermissionGuard
y solo comience a verificar los permisos si se ha determinado la autenticación.
require-authentication.guard.ts
constructor(
private userSessionSerivce: UserSessionService)
canActivate(
_route: ActivatedRouteSnapshot,
state: RouterStateSnapshot,
): Observable
return this.validateAuthentication(state.url);
require-permission.guard.ts
constructor(
private permissionService: PermissionService,
/**
* We use the RequireAuthenticationGuard internally
* since Angular does not provide ordered deterministic guard execution in route definitions
*
* We only check permissions once authentication state has been determined
*/
private requireAuthenticationGuard: RequireAuthenticatedGuard,
)
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot,
): Observable
Usando un Maestro de la guardia para disparar, los protectores de aplicaciones pueden hacer el truco.
EDITAR: agregando el fragmento de código para una mejor comprensión.
Enfrenté un problema similar y así es como lo resolví:
Solución
La idea es crear un maestro de la guardia y dejar que el maestro de la guardia se encargue de la ejecución de otros guardias.
El configuración de enrutamiento en este caso, contendrá maestro de la guardia como el único guardia.
Para que el guardia maestro sepa sobre los guardias que se activarán para rutas específicas, agregue un data
propiedad en Route
.
El data
la propiedad es una key par de valores que nos permite adjuntar datos con las rutas.
A continuación, se puede acceder a los datos en los guardias utilizando ActivatedRouteSnapshot
parámetro de canActivate
método en la guardia.
La solución parece complicada, pero garantizará el funcionamiento adecuado de las protecciones una vez que se integre en la aplicación.
El siguiente ejemplo explica este enfoque:
Ejemplo
1. Objeto de constantes para mapear todos los protectores de aplicaciones –
export const GUARDS =
GUARD1: "GUARD1",
GUARD2: "GUARD2",
GUARD3: "GUARD3",
GUARD4: "GUARD4",
2. Protección de aplicaciones –
import Injectable from "@angular/core";
import Guard4DependencyService from "./guard4dependency";
@Injectable()
export class Guard4 implements CanActivate
//A guard with dependency
constructor(private _Guard4DependencyService: Guard4DependencyService)
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise
return new Promise((resolve: Function, reject: Function) =>
//logic of guard 4 here
if (this._Guard4DependencyService.valid())
resolve(true);
else
reject(false);
);
3. Configuración de enrutamiento –
import Route from "@angular/router";
import View1Component from "./view1";
import View2Component from "./view2";
import MasterGuard, GUARDS from "./master-guard";
export const routes: Route[] = [
path: "view1",
component: View1Component,
//attach master guard here
canActivate: [MasterGuard],
//this is the data object which will be used by
//masteer guard to execute guard1 and guard 2
data:
guards: [
GUARDS.GUARD1,
GUARDS.GUARD2
]
,
path: "view2",
component: View2Component,
//attach master guard here
canActivate: [MasterGuard],
//this is the data object which will be used by
//masteer guard to execute guard1, guard 2, guard 3 & guard 4
data:
guards: [
GUARDS.GUARD1,
GUARDS.GUARD2,
GUARDS.GUARD3,
GUARDS.GUARD4
]
];
4. Maestro de la guardia –
import Injectable from "@angular/core";
import CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router from "@angular/router";
//import all the guards in the application
import Guard1 from "./guard1";
import Guard2 from "./guard2";
import Guard3 from "./guard3";
import Guard4 from "./guard4";
import Guard4DependencyService from "./guard4dependency";
@Injectable()
export class MasterGuard implements CanActivate
//you may need to include dependencies of individual guards if specified in guard constructor
constructor(private _Guard4DependencyService: Guard4DependencyService)
private route: ActivatedRouteSnapshot;
private state: RouterStateSnapshot;
//This method gets triggered when the route is hit
public canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise
this.route = route;
this.state = state;
if (!route.data)
Promise.resolve(true);
return;
//this.route.data.guards is an array of strings set in routing configuration
if (!this.route.data.guards
//Execute the guards sent in the route data
private executeGuards(guardIndex: number = 0): Promise
return this.activateGuard(this.route.data.guards[guardIndex])
.then(() =>
if (guardIndex < this.route.data.guards.length - 1)
return this.executeGuards(guardIndex + 1);
else
return Promise.resolve(true);
)
.catch(() =>
return Promise.reject(false);
);
//Create an instance of the guard and fire canActivate method returning a promise
private activateGuard(guardKey: string): Promise Guard3
Desafíos
Uno de los desafíos de este enfoque es la refactorización del modelo de enrutamiento existente. Sin embargo, se puede hacer por partes, ya que los cambios no se romperán.
Espero que esto ayude.
Eche un vistazo a esta guía angular (enlace). “Si estuviera utilizando una API del mundo real, podría haber un retraso antes de que el servidor devuelva los datos que se mostrarán. No desea mostrar un componente en blanco mientras espera los datos.
Es preferible obtener previamente los datos del servidor para que estén listos en el momento en que se activa la ruta. Esto también le permite manejar errores antes de enrutar al componente …
En resumen, desea retrasar la renderización del componente enrutado hasta que se hayan obtenido todos los datos necesarios.
Necesitas un solucionador “.
Te invitamos a añadir valor a nuestro contenido informacional aportando tu experiencia en las crónicas.