Reputation: 3791
I have the next Angular Guard:
export class AdminGuard implements CanActivate {
constructor(
private readonly router: Router,
private readonly userService: UserService
) { }
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
return this.userService.getUserRoles().pipe(
map(roles => {
if (roles.admin) {
return true
}
this.router.navigate(['/'])
return false
})
)
}
}
This is method from the service, which return Observable:
public getUserRoles(): Observable<any> {
return this.store.pipe(
select('user'),
map(({ roles }) => roles)
)
}
And this is works when I navigate between page, but when I directly enter in URL some route, for example 'myapp.com/admin', it returns false automatically and the guard does not work. How to make it work properly?
Upvotes: 0
Views: 739
Reputation: 29786
Best guess, when entering the url directly in the browser, you are restarting your application and the store is reset to defaults with no user.
You should rewrite your getUserRoles()
method to check if the user has been authenticated before reading roles, and not just read store state. If you are using OAuth2, for example, this would redirect the user to your authentication endpoint passing appropriate state to resume on the myapp.com/admin
route once re-authentication handshake is complete and the store is populated.
The specifics of this will very much depend on what authentication approach you are using.
Upvotes: 1