Search code examples
angularangular-route-guards

Angular route guard executed before user authentication


I implemented a simple route guard that redirects to the login page if a user is not authenticated, where the check for login is of type Observable.

The guard is working as expected, but if the user is logged-in, navigates to a protected page:

{ path: 'protected-page', component: ProtectedComponent, canActivate: [authGuard] },

and reloads (ctrl+f5) the page, the user is redirected to the login page (because BehaviorSubject emits false by default). But if I switch to Subject the page is still loading and does not return.

I want the user is also redirected to the protected page again, if userService emits that this user is already logged-in. Or the route guard should wait till user-service emits the login status.

auth.guad.ts:

export const authGuard: CanActivateFn = (route, state): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree => {
    const userService = inject( UserProfileService );
    const router = inject( Router );
      return userService.isLoggedIn().pipe(
        //take(1),
        map((loggedIn: boolean) => {
          if (loggedIn)
            return true;
          return router.createUrlTree(['/sign-in']);
        })
      );
  };

user-profile.service.ts

...
private loggedInSubject = new BehaviorSubject<boolean>(false);
...
isLoggedIn(): Observable<boolean>{
  return this.loggedInSubject.asObservable();   
}
... 

Solution

  • When the user logs in, try storing the authentication token in the browser's session storage. Then in the isLoggedIn function of UserProfileService, check if the auth token is in the session storage to tell if the user is logged in.

    isLoggedIn(): boolean {
      const authToken = sessionStorage.getItem('AuthToken');
      return !!authToken;
    }