Home > Software design >  Gets stuck loading a component that isn't logged in
Gets stuck loading a component that isn't logged in

Time:05-20

I have a problem when redirecting when a user is not logged in. In my project I have two Guards for the Admin and User, then I use the functions of the @angular/fire/auth-guard library to redirect if logged in and if not. The problem is if I add my guards that I created myself, the guard that checks whether you are logged in or not of each component stops working, which keeps the page loading and never ends, instead mine does work . Here is an example of my code:

In this code that I have both the RolUserGuard and the RoleAdminGuard work, but the AuthGuard of home and admin do not work, they get caught loading without returning to the login page. Instead if you are logged in and try to redirect to the login page the AuthGuard works.

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}
]

Am I doing something wrong? Could it be because of the data property and that when adding a second Guard it does not detect it correctly? anything helps

I leave you the code of the other guards, although it is practically the same only that it changes instead of amin for user and vice versa.

  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;
  }

CodePudding user response:

My solution for this situation is, remove authGurad and use UserService in each guard to check user is logged in:

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;
}

And you should do same thing for RoleUserGuard with the different condition (role).

Or

We can use user dictionary like this in the UserService.
UserService:

userAccess= {
  home: 'user',
  admin: 'admin'
}

And just use one guard (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;
}

I hope this help you.

  • Related