From b7c3a1bf46c49c1a29bb4cfd3161f115a4b055f2 Mon Sep 17 00:00:00 2001 From: Kevin Schmidt Date: Sun, 13 Sep 2020 13:10:05 +0200 Subject: [PATCH] changed auth guard to wait for auth process to finish to prevent multiple login calls resulting in a wrong redirect --- 01-Login/src/app/auth/auth.guard.ts | 9 +++++---- 01-Login/src/app/auth/auth.service.ts | 7 +++++++ 02-Calling-an-API/src/app/auth/auth.guard.ts | 9 +++++---- 02-Calling-an-API/src/app/auth/auth.service.ts | 7 +++++++ 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/01-Login/src/app/auth/auth.guard.ts b/01-Login/src/app/auth/auth.guard.ts index 440ef415..073d4eb3 100644 --- a/01-Login/src/app/auth/auth.guard.ts +++ b/01-Login/src/app/auth/auth.guard.ts @@ -7,7 +7,7 @@ import { } from '@angular/router'; import { Observable } from 'rxjs'; import { AuthService } from './auth.service'; -import { tap } from 'rxjs/operators'; +import { skipWhile, switchMap, tap } from 'rxjs/operators'; @Injectable({ providedIn: 'root' @@ -20,13 +20,14 @@ export class AuthGuard implements CanActivate { next: ActivatedRouteSnapshot, state: RouterStateSnapshot ): Observable | Promise | boolean { - return this.auth.isAuthenticated$.pipe( + return this.auth.isAuthInProgress$.pipe( + skipWhile((inProgress: boolean) => inProgress), + switchMap(inProgress => this.auth.isAuthenticated$), tap(loggedIn => { if (!loggedIn) { this.auth.login(state.url); } - }) - ); + })); } } diff --git a/01-Login/src/app/auth/auth.service.ts b/01-Login/src/app/auth/auth.service.ts index 85e27044..961fabf8 100644 --- a/01-Login/src/app/auth/auth.service.ts +++ b/01-Login/src/app/auth/auth.service.ts @@ -35,6 +35,9 @@ export class AuthService { // Create subject and public observable of user profile data private userProfileSubject$ = new BehaviorSubject(null); userProfile$ = this.userProfileSubject$.asObservable(); + + isAuthInProgress$ = new BehaviorSubject(false); + // Create a local property for login status loggedIn: boolean = null; @@ -89,6 +92,8 @@ export class AuthService { // Call when app reloads after user logs in with Auth0 const params = window.location.search; if (params.includes('code=') && params.includes('state=')) { + this.isAuthInProgress$.next(true); + let targetRoute: string; // Path to redirect to after login processsed const authComplete$ = this.handleRedirectCallback$.pipe( // Have client, now call method to handle auth callback redirect @@ -107,6 +112,8 @@ export class AuthService { // Subscribe to authentication completion observable // Response will be an array of user and login status authComplete$.subscribe(([user, loggedIn]) => { + this.isAuthInProgress$.next(false); + // Redirect to target route after callback processing this.router.navigateByUrl(targetRoute); }); diff --git a/02-Calling-an-API/src/app/auth/auth.guard.ts b/02-Calling-an-API/src/app/auth/auth.guard.ts index 440ef415..073d4eb3 100644 --- a/02-Calling-an-API/src/app/auth/auth.guard.ts +++ b/02-Calling-an-API/src/app/auth/auth.guard.ts @@ -7,7 +7,7 @@ import { } from '@angular/router'; import { Observable } from 'rxjs'; import { AuthService } from './auth.service'; -import { tap } from 'rxjs/operators'; +import { skipWhile, switchMap, tap } from 'rxjs/operators'; @Injectable({ providedIn: 'root' @@ -20,13 +20,14 @@ export class AuthGuard implements CanActivate { next: ActivatedRouteSnapshot, state: RouterStateSnapshot ): Observable | Promise | boolean { - return this.auth.isAuthenticated$.pipe( + return this.auth.isAuthInProgress$.pipe( + skipWhile((inProgress: boolean) => inProgress), + switchMap(inProgress => this.auth.isAuthenticated$), tap(loggedIn => { if (!loggedIn) { this.auth.login(state.url); } - }) - ); + })); } } diff --git a/02-Calling-an-API/src/app/auth/auth.service.ts b/02-Calling-an-API/src/app/auth/auth.service.ts index f9088478..822474a2 100644 --- a/02-Calling-an-API/src/app/auth/auth.service.ts +++ b/02-Calling-an-API/src/app/auth/auth.service.ts @@ -36,6 +36,9 @@ export class AuthService { // Create subject and public observable of user profile data private userProfileSubject$ = new BehaviorSubject(null); userProfile$ = this.userProfileSubject$.asObservable(); + + isAuthInProgress$ = new BehaviorSubject(false); + // Create a local property for login status loggedIn: boolean = null; @@ -98,6 +101,8 @@ export class AuthService { // Call when app reloads after user logs in with Auth0 const params = window.location.search; if (params.includes('code=') && params.includes('state=')) { + this.isAuthInProgress$.next(true); + let targetRoute: string; // Path to redirect to after login processsed const authComplete$ = this.handleRedirectCallback$.pipe( // Have client, now call method to handle auth callback redirect @@ -116,6 +121,8 @@ export class AuthService { // Subscribe to authentication completion observable // Response will be an array of user and login status authComplete$.subscribe(([user, loggedIn]) => { + this.isAuthInProgress$.next(false); + // Redirect to target route after callback processing this.router.navigate([targetRoute]); });