I have an observable to check if the user is loggedIn or not. I set that observable from auth api which is called from appComponent when application starts.
export class AppComponent implements OnInit {
loggedIn$: Observable<boolean | null>;
constructor(private userService:UserService) {
this.userService.authenticate();
}
ngOnInit(): void {
//to show header when loggedin
this.loggedIn$ = this.userService.isAuthenticated;
}
}
and I have AuthGaurd which restricts unauthenticated users from navigating to inner pages.
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | UrlTree | Observable<boolean | UrlTree> | Promise<boolean | UrlTree> {
return this.userService.isAuthenticated.pipe(
take(1),
map((loggedin:boolean) => {
if(loggedin) {
//checking for required permissions as well
let permission = route.data['permission'];
if( this.userService.hasPermission(permission)) {
return true;
}
}
this.router.navigate(['unauthorised-user', { page: state.url}]);
return false;
})
);
}
and here's aut service
private loggedIn: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
public authenticate() {
this.http.get<User>('<auth-api-url')
.subscribe(
(response: user) => {
this.user = response;
if (this.user) {
document.cookie = `coockie`;
this.loggedIn.next(true);
this.getReferenceData();
}else {
this.loggedIn.next(false);
}
}
);
}
get isAuthenticated(): Observable<boolean> {
return this.loggedIn.asObservable();
}
public hasPermission(permission:string): boolean {
return this.user?.permissions?.includes(permission);
}
when I launch the app "/" appComponent makes call to auth api but auth guard checks and redirects user to unauthorised-user page as auth api hasn't finished yet.
I have looked at few solutions which adds auth api call into canActivate guard but then it calls api every time I navigate to different page. I would like to call the api once and then set the flag (observable) in auth service which other components can use to check if user is authenticated or not.
Thanks