When my user browses, a Guard checks the token and updates it, otherwise it disconnects the user. The update is done by calling a Rxjs Effect function in Angular. But after each execution of the secondary effect, my application redirects to the home component instead of navigating to the target chosen by the user.
<code>#Effect Function:
import { Injectable } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { RootActions } from '../actions/actions';
import { of, map, catchError, Observable, mergeMap, tap } from 'rxjs';
import { AuthService } from '../../auth/services/auth.service';
import { RootState } from '../reducers/reducer';
import { Store } from '@ngrx/store';
import { getAuthToken } from '../selectors/selectors';
import { ActivatedRouteSnapshot, NavigationEnd, NavigationStart, Router } from '@angular/router';
import { StorageManagementService } from '../../auth/services/storage-management.service';
@Injectable()
export class TokenEffects {
token: string = '';
observable: Observable<string> = new Observable();
constructor(
private actions$: Actions,
private authService: AuthService,
private store: Store<RootState>,
private router: Router,
) {
this.store.select(getAuthToken).subscribe(token => (this.token = token));
}
loadToken$ = createEffect(() =>
this.actions$.pipe(
ofType(RootActions.loadToken),
mergeMap(action =>
this.authService.renewToken(this.token).pipe(
map(response =>
RootActions.setAuthTokenValue({ authToken: response.authToken })
),
catchError(error =>
of(RootActions.loadTokenFailure({ error: 'errer' }))
)
)
)
)
);
}
#AuthGuard :
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<boolean | UrlTree> {
return this.authService.jwtToken$.pipe(
take(1),
switchMap(isAuthenticated => {
if (!isAuthenticated.isAuthenticated) {
return this.authService.getIfIsInAProdEnv().pipe(
map(isUseSAML => {
const isProdEnv = isUseSAML;
return this.redirectToLoginPage(isProdEnv);
})
);
} else if (isAuthenticated.token) {
return this.authService.renewToken(isAuthenticated.token).pipe(
switchMap(response => {
if (response && response.authToken) {
this.store.dispatch(RootActions.loadToken());
return this.checkAccess(route);
} else {
this.store.dispatch(RootActions.logout());
return of(this.redirectToLoginPage(false));
}
}),
catchError(err => {
this.store.dispatch(RootActions.logout());
return of(this.redirectToLoginPage(false));
})
);
} else {
return this.checkAccess(route);
}
}),
catchError(err => {
this.store.dispatch(RootActions.logout());
return of(this.redirectToLoginPage(false));
})
);
}
</code>
<code>#Effect Function:
import { Injectable } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { RootActions } from '../actions/actions';
import { of, map, catchError, Observable, mergeMap, tap } from 'rxjs';
import { AuthService } from '../../auth/services/auth.service';
import { RootState } from '../reducers/reducer';
import { Store } from '@ngrx/store';
import { getAuthToken } from '../selectors/selectors';
import { ActivatedRouteSnapshot, NavigationEnd, NavigationStart, Router } from '@angular/router';
import { StorageManagementService } from '../../auth/services/storage-management.service';
@Injectable()
export class TokenEffects {
token: string = '';
observable: Observable<string> = new Observable();
constructor(
private actions$: Actions,
private authService: AuthService,
private store: Store<RootState>,
private router: Router,
) {
this.store.select(getAuthToken).subscribe(token => (this.token = token));
}
loadToken$ = createEffect(() =>
this.actions$.pipe(
ofType(RootActions.loadToken),
mergeMap(action =>
this.authService.renewToken(this.token).pipe(
map(response =>
RootActions.setAuthTokenValue({ authToken: response.authToken })
),
catchError(error =>
of(RootActions.loadTokenFailure({ error: 'errer' }))
)
)
)
)
);
}
#AuthGuard :
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<boolean | UrlTree> {
return this.authService.jwtToken$.pipe(
take(1),
switchMap(isAuthenticated => {
if (!isAuthenticated.isAuthenticated) {
return this.authService.getIfIsInAProdEnv().pipe(
map(isUseSAML => {
const isProdEnv = isUseSAML;
return this.redirectToLoginPage(isProdEnv);
})
);
} else if (isAuthenticated.token) {
return this.authService.renewToken(isAuthenticated.token).pipe(
switchMap(response => {
if (response && response.authToken) {
this.store.dispatch(RootActions.loadToken());
return this.checkAccess(route);
} else {
this.store.dispatch(RootActions.logout());
return of(this.redirectToLoginPage(false));
}
}),
catchError(err => {
this.store.dispatch(RootActions.logout());
return of(this.redirectToLoginPage(false));
})
);
} else {
return this.checkAccess(route);
}
}),
catchError(err => {
this.store.dispatch(RootActions.logout());
return of(this.redirectToLoginPage(false));
})
);
}
</code>
#Effect Function:
import { Injectable } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { RootActions } from '../actions/actions';
import { of, map, catchError, Observable, mergeMap, tap } from 'rxjs';
import { AuthService } from '../../auth/services/auth.service';
import { RootState } from '../reducers/reducer';
import { Store } from '@ngrx/store';
import { getAuthToken } from '../selectors/selectors';
import { ActivatedRouteSnapshot, NavigationEnd, NavigationStart, Router } from '@angular/router';
import { StorageManagementService } from '../../auth/services/storage-management.service';
@Injectable()
export class TokenEffects {
token: string = '';
observable: Observable<string> = new Observable();
constructor(
private actions$: Actions,
private authService: AuthService,
private store: Store<RootState>,
private router: Router,
) {
this.store.select(getAuthToken).subscribe(token => (this.token = token));
}
loadToken$ = createEffect(() =>
this.actions$.pipe(
ofType(RootActions.loadToken),
mergeMap(action =>
this.authService.renewToken(this.token).pipe(
map(response =>
RootActions.setAuthTokenValue({ authToken: response.authToken })
),
catchError(error =>
of(RootActions.loadTokenFailure({ error: 'errer' }))
)
)
)
)
);
}
#AuthGuard :
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<boolean | UrlTree> {
return this.authService.jwtToken$.pipe(
take(1),
switchMap(isAuthenticated => {
if (!isAuthenticated.isAuthenticated) {
return this.authService.getIfIsInAProdEnv().pipe(
map(isUseSAML => {
const isProdEnv = isUseSAML;
return this.redirectToLoginPage(isProdEnv);
})
);
} else if (isAuthenticated.token) {
return this.authService.renewToken(isAuthenticated.token).pipe(
switchMap(response => {
if (response && response.authToken) {
this.store.dispatch(RootActions.loadToken());
return this.checkAccess(route);
} else {
this.store.dispatch(RootActions.logout());
return of(this.redirectToLoginPage(false));
}
}),
catchError(err => {
this.store.dispatch(RootActions.logout());
return of(this.redirectToLoginPage(false));
})
);
} else {
return this.checkAccess(route);
}
}),
catchError(err => {
this.store.dispatch(RootActions.logout());
return of(this.redirectToLoginPage(false));
})
);
}