angular - Se queda atascado cargando un componente que no está registrado
Tengo un problema al redirigir cuando un usuario no ha iniciado sesión. En mi proyecto tengo dos Guards para el Administrador y el Usuario, luego uso las funciones de la librería @angular/fire/auth-guard para redirigir si está conectado y si no. El problema es que si agrego mis guards que creé yo mismo, el guard que verifica si estás conectado o no en cada componente deja de funcionar, lo que hace que la página siga cargando y nunca termine, mientras que el mío sí funciona. Aquí hay un ejemplo de mi código:
En este código que tengo tanto el RolUserGuard como el RoleAdminGuard funcionan, pero el AuthGuard de home y admin no funciona, se quedan cargando sin regresar a la página de inicio de sesión. En cambio, si estás conectado e intentas redirigirte a la página de inicio de sesión, el AuthGuard funciona.
const redirectUnauthorizedToLogin = () => redirectUnauthorizedTo(['']);
const redirectLoggedInToHome = () => redirectLoggedInTo(['home']);
const routes : Routes = [
{path : '',redirectTo: 'login', pathMatch: 'full'},
{path : 'login', component : LoginComponent, canActivate: [AuthGuard], data: {authGuardPipe: redirectLoggedInToHome}},
{path : 'home', component : HomeComponent, canActivate: [AuthGuard,RoleUserGuard], data: {authGuardPipe: redirectUnauthorizedToLogin} },
{path : 'admin', component : AdminComponent, canActivate: [AuthGuard,RoleAdminGuard], data: {authGuardPipe: redirectUnauthorizedToLogin}, children:[
{path : '', component : AdminUsersComponent},
{path : 'user/:id', component: DetailsComponent}
]},
{path : '**', component: PageNotFoundComponent}
]
¿Estoy haciendo algo mal? ¿Podría ser por la propiedad data y que al agregar un segundo Guard no lo detecta correctamente? Cualquier cosa ayuda
Te dejo el código de los otros guardias, aunque es prácticamente el mismo, solo que cambia en lugar de amin por usuario y viceversa.
canActivate( route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
const rol = localStorage.getItem('rolUser');
if(rol!=='admin'){
this.router.navigate(['/home']);
return false;
}
return true;
}
Respuesta #1
Mi solución para esta situación es, eliminar authGuard y usar UserService en cada guardia para verificar si el usuario ha iniciado sesión:
RoleAdminGuard :
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
const isLoggedIn = this.userService.isLoggedIn();
if (!isLoggedIn) {
this.router.navigate(['/login']);
return false;
}
const rol = localStorage.getItem('rolUser');
if (rol !== 'admin'){
this.router.navigate(['/home']);
return false;
}
return true;
}
Y deberías hacer lo mismo para RoleUserGuard con la condición diferente (rol).
O
Podemos usar un diccionario de usuarios así en el UserService.
UserService:
userAccess= {
home: 'user',
admin: 'admin'
}
Y solo utiliza un guardia (RoleGuard)
RoleGuard:
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
const isLoggedIn = this.userService.isLoggedIn();
if (!isLoggedIn) {
this.router.navigate(['/login']);
return false;
}
const rol = localStorage.getItem('rolUser');
const userAccess = this.userService.userAccess[next.url]
if (rol !== userAccess) {
const navigateTo = rol === 'admin' ? '/admin' : '/home';
this.router.navigate([navigateTo]);
return false;
}
return true;
}
Espero que esto te ayude.
