Routing doesn't work correctly when user is authentication

543 views Asked by At

So, I have a problem in a project with routing. I follow this steps.

  1. When Logon in system I save token and username in local storage.
  2. Login success, open dashboard page.
  3. I close browser and open again project. Page routing in Login page , no in dashboard page, only when I put correct url page routing ok. So data are in local storage. In this part I want to routing page in Dashboard page, not in login, only when I have data user in local storage. If local storage is empty I want to routing in Login Page

I have this routing:

const routes: Routes = [
  { path: 'login', component: LoginComponent },
  { path: 'forgotpassword', component: ForgotPasswordComponent },
  { path: '', component: LoginComponent },
  { path: 'panel', canActivate: [AuthGuard], loadChildren: () => import('./panel/panel.module').then(m => m.PanelModule) }
];

And this routing panel.

const routes: Routes = [
  {
    path: '',
    component: PanelComponent,
    canActivate: [AuthGuard],
    canActivateChild: [AuthGuard],
    children: [
      {
        path: '',
        pathMatch: 'full',
        redirectTo: 'dashboard'
      },
      {
        path: 'dashboard',
        component: DashboardComponent,
        data: { allowedRoles: [Role.COMMUNITY_ADMIN] }
      },
      .....
      {
        path: 'documents',
        component: DocumentComponent,
        data: { allowedRoles: [Role.CHAIRMAN] }
      },
    ]
  }
];

I have and this Authguard.

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
      if (this.authService.currentUserLogged){
      return true;
    }
    this.router.navigateByUrl('/');
    return false;
  }

  canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
    if (this.authService.currentUserLogged) {
      const userRoles = currentUserLogged.user?.user_roles;
      const allowedRoles = route.data.allowedRoles;
      return this.authService.isAuthorized(allowedRoles, userRoles);
    }
    this.router.navigateByUrl('/');
    return false;
  }

UPDATE

authservice.ts

currentUserLogged!: IUserLoggedInAccountDTO;

     constructor(protected httpClient: HttpClient, private router: Router) {
        this.currentUserLogged = this.getUserLoggedInAccount();
      }
    
      private getUserLoggedInAccount = (): IUserLoggedInAccountDTO => (JSON.parse(localStorage.getItem(environment.userLoggedInAccountLocalStorageKey) || '{}'));
    
      isAuthorized(allowedRoles: any, userRoles: any): boolean {
        if (allowedRoles === null || allowedRoles?.length === 0) {
          return true;
        }
        if (userRoles !== null && userRoles?.length !== 0) {
          const userRolesFiltered = userRoles.filter((userRole: any) => formatDate(userRole.end_date, 'yyyy-MM-dd', 'en_US') >= formatDate(new Date(), 'yyyy-MM-dd', 'en_US'));
          const authorise: boolean = userRolesFiltered.some((userRole: any) => allowedRoles.includes(userRole.role.name));
          if (!authorise) {
            this.router.navigate(['/']);
            return false;
          }
          return true;
        }
        return false;
      }

Thank you so for your answer!

1

There are 1 answers

5
N.F. On BEST ANSWER

You have to redirect to Dashboard page when accessed to root page.

const routes: Routes = [
  { path: 'login', component: LoginComponent },
  { path: 'forgotpassword', component: ForgotPasswordComponent },
  { path: '', redirectTo: '/panel/dashboard', pathMatch: 'full' },
  { path: 'panel', canActivate: [AuthGuard], loadChildren: () => import('./panel/panel.module').then(m => m.PanelModule) }
];

And you have to navigate to Login page when not logged in.

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
    if (this.authService.currentUserLogged.user){
      return true;
    }
    this.router.navigateByUrl('/login');
    return false;
  }

  canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
    if (this.authService.currentUserLogged.user) {
      const userRoles = currentUserLogged.user.user_roles;
      const allowedRoles = route.data.allowedRoles;
      return this.authService.isAuthorized(allowedRoles, userRoles);
    }
    this.router.navigateByUrl('/login');
    return false;
  }

Update

You should navigate to /login before return false in authservice.ts

        if (userRoles !== null && userRoles?.length !== 0) {
          const userRolesFiltered = userRoles.filter((userRole: any) => formatDate(userRole.end_date, 'yyyy-MM-dd', 'en_US') >= formatDate(new Date(), 'yyyy-MM-dd', 'en_US'));
          const authorise: boolean = userRolesFiltered.some((userRole: any) => allowedRoles.includes(userRole.role.name));
          if (!authorise) {
            this.router.navigate(['/login']);
            return false;
          }
          return true;
        }
        this.router.navigate(['/login']);
        return false;