I am working on setting up AuthGuard for routes in an Angular 2 application. Each route has different user groups that can go to that route. On the front-end I am only storing a bearer token so when canActivate is called I want to call an API, send in my token and route, let the API resolve whether or not that user has access to that route and if they do, return a true, otherwise return a false. On the front-end, I want to use the results from that call to either route them or just send them back to the login screen.
This is how I am trying to accomplish that:
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
this.authService.authenticateRouteForUser(state.url).subscribe(active => {
if (active) {
return true;
}
this.authService.redirectUrl = state.url;
this.router.navigate(['/login-page'])
return false;
})
}
The logic within the subscribe works because I have tested it like this (This is essentially taken right from the Angular documentation by Google):
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean{
console.log('AuthGuard#canActivate called')
if(this.authService.isLoggedIn){
return true;
}
this.authService.redirectUrl = state.url;
this.router.navigate(['/login-page'])
return false;
}
I know that the problem with my first statement is that the canActivate has to return a true or a false and I am only returning a true or a false within the subscribe. The problem is I only want to return a true or a false after the route authentication has happened, which requires a call to the API. Am I approaching this all wrong? Should I just return user roles on login and store the roles for each route on the front-end so I can just check that without doing a call? Is there some other way to approach this that I am missing?