As the title suggests, I want to protect routes via canLoad. This works to some extent. However, I have two issues with the code.
Here are my code snippets
AppComponent
ngOnInit(): void {
this.authServ.reauthenticate().subscribe()
}
AuthService
user = new BehaviorSubject<User>(null as any);
reauthenticate(): Observable<User> {
// return HTTP call here and pipe the user data into user BehaviorSubject
}
AuthGuard
canLoad(){
return this.authServ.user.pipe(
map((user) => {
if (!!user?._token) {
return true;
}
this.router.navigate(['/login']);
return false;
})
);
}
As you can guess, the router can access the user but still redirects to the /login path. Knowing it doesn't work, I brute-forced my way, making two HTTP calls to the server (which is generally bad, I know) to trick the system into acknowledging a persistent user. Here is the code snippet.
AuthGuard
canLoad() {
return this.authServ.user.pipe(
switchMap((user) => {
if (!!user && !!user._token) {
return of(user);
}
return this.authServ.reauthenticate();
}),
map((user) => {
if (!!user?._token) {
return true;
}
this.router.navigate(['/login']);
return false;
})
);
}
So my question boils down to either of these two things:
- How can I make sure that I only call the re-tokenizer endpoint only once but still not continue to not be routed upon refresh?
- How can I make the BehaviorSubject work until I receive a user object?
I have checked the following links:
AuthGuard router angular
and What is the difference between Subject and BehaviorSubject?. However, upon using a Subject, I may need to reauthenticate the user every time I visit a guarded route which is counterintuitive.