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();
}
...
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;
}