0
votes

I'm trying to route the user to different components after login, based on roles.

But when I route, I get an infinite loop in canActivate as route url is always empty, which should only be true the first time, second time it should be either the path "/admin" or "/user".

App-routing.module.ts

const routes : Routes = [
  { path : ''  , redirectTo : '', pathMatch: 'full' , canActivate : [RedirectGuardService] },
  { path : 'admin' , component : DashboardComponent , canActivate : [AuthGuardService], data : { role : 'admin'}},
  { path : 'user' , component : UserComponent , canActivate : [AuthGuardService], data : { role : 'user'}},
];

Redirect-guard.service.ts

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) : Observable<boolean> | Promise<boolean> | boolean {
  const role = localStorage.getItem("role");
  if (role) {  
    alert("navigate to the right detination based on role");    
    this.router.navigate(['/'+ role]);
    return true;      
  }      
  this.router.navigate(['/login'], { queryParams: { returnUrl: state.url }});
  return false;
}
  • I did not include the code for AuthGuardService as it never hits that code.
  • alert("navigate to the right detination based on role"); gets displayed infinite.
  • route: ActivatedRouteSnapshot is always empty: (url:'')
2
Your first route in the configuration, '' redirects to ''. Maybe that is causing the infinite loop? - joshrathke
It might be, I'll test it. - Michael Winther
As a small suggestion seems odd you’re making a decision on the role and where or navigate depending on what is read from the local storage. You do know that anyone can edit it at any point in time and alter their role to admin, right? Just a small reminder of security concerns :) - Hugo Noro
Yes I know, they can change their role, but they will only be able to view the graphical part, because I have secured the backend, so they can't get any data anyway. From what I read, it should be the perfered way to handle roles. - Michael Winther

2 Answers

0
votes

Turned out to be the role I got from localStorage.getItem("role") was with capital first letter and the routing data role were all lowercase, so ended up not finding the url and ran infinite. Its still a bad behavior as route ** should have grabed that. But I can move on for now.

0
votes

EDIT: Found out the culprit! In app.module.ts you need to import AuthModule first. Doing this will allow you to use the path '**' in either 'auth-routing.module.ts' or 'app-routing.module.ts'

@NgModule({

  imports: [
    AuthModule,
    AppRoutingModule,
    BrowserModule,
    HttpClientModule,
    SharedModule
  ],
})

I was having an infinite loop issue as well. Not sure if this relates to yours but for me I had two routing files. 'app-routing.module.ts' and 'auth-routing.module.ts'. I moved the code below from ' app-routing.module.ts' into 'auth-routing.module.ts' and no more infinite loops! Hope this helps you in some way!

 {
    path: '**',
    redirectTo: 'my-route',
  }