My application has routes protected by an AuthGuard that implements CanActivate. This guard first checks if the user is logged in and then verifies if certain configuration variables are set before allowing access to the route. If the user is authenticated but the necessary configurations are missing, the AuthGuard makes an HTTP call to retrieve them and only permits access once the call is successfully resolved (otherwise denies it).
The problem arises when the Router cancels the navigation before the configuration retrieval process is completed.
Here is the canActivate method of the AuthGuard:
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
let authenticated = this.isAuthenticated();
if (authenticated) {
console.log("User authenticated, checking for configs...");
if (this.config.defined) {
console.log("Config defined!");
return true;
} else {
***** HERE ******
console.log("Config not defined, setting configs...");
this.authService.setConfig()
.take(1)
.subscribe(
config => {
// SET CONFIG VARIABLES
console.log("Config variables set");
// allow route access
return true;
},
err => {
console.error(err);
this.router.navigate(['/Login']);
return false;
}
);
this.router.navigate(['/Login']);
return false;
}
} else {
console.log("User not authenticated, back to login");
this.router.navigate(['/Login']);
return false;
}
}
When I am logged in but the configuration variables are not yet established, and attempt to access a page (marked as **** HERE ****
), the console logs:
Setting config...
NavigationCancel {id: 1, url: "/", reason: ""}
NavigationStart {id: 2, url: "/Login"}
RoutesRecognized {id: 2, url: "/Login", urlAfterRedirects: "/Login", state: RouterStateSnapshot}
NavigationEnd {id: 2, url: "/Login", urlAfterRedirects: "/Login"}
Config variables set
Before the AuthGuard's configuration HTTP call can finish, the navigation is cancelled and the router redirects as if the AuthGuard had returned false. I am looking for a solution to ensure that the AuthGuard's result is based on the resolution of the HTTP call.