I use Auth0 from the latest Auth0 Angular SDK (v.1.8.2.) with Angular 13 and rxjs 7.4.0, and want to do the following:
- if authorized, always fetch profile data from the user globally
- have a guard which checks the profile data on some pages
I use the Auth0 Guard along with a custom Profile Guard for checking the profile data.
Problem: If I refresh the page, my Auth0 Guard would return true but my Profile Guard would always return false as my app did not yet fetch the profile data.
export class AuthService {
profile: BehaviorSubject<Profile| undefined> = new BehaviorSubject<Profile| undefined>(undefined);
public readonly profile$: Observable<Profile| undefined> = this.profile.asObservable();
constructor(
@Inject(DOCUMENT) private doc: Document,
public auth0: Auth0Service,
private httpHandler: HttpHandlerService
) {
this.auth0.isAuthenticated$.subscribe((isAuth) => {
if (isAuth) {
this.httpHandler.fetchProfile().subscribe(
(profile: Profile) => this.profile.next(profile))
}
})
}
}
export class ProfileGuard implements CanActivate, CanActivateChild {
constructor(private auth: AuthService, private router: Router) {
}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): true | UrlTree {
return this.checkProfile(state.url);
}
canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot): true | UrlTree {
return this.checkProfile(childRoute, state);
}
checkLogin(url: string): true | UrlTree {
//how "wait" for the auth service to finish fetching the profile data?
if (this.auth.profile.value?.isBaned!== true)
return true;
return this.router.parseUrl('/banned');
}
}
In my app routing, I use both the Auth0 Guard and my custom guard as follows:
const routes: Routes = [
{ path: 'myProtectedRoute', component: UserComponent, canActivate: [Auth0Guard, ProfileGuard], runGuardsAndResolvers: 'always' }
]
How can I rewrite my profile guard to have it wait for the profile data to be fetched before proceeding?
Thanks in advance