Added redirect to login whether token is expired

This commit is contained in:
Giuseppe Digilio
2018-04-04 13:32:02 +02:00
parent 5fc6d4ead8
commit f841612e1c
4 changed files with 34 additions and 10 deletions

View File

@@ -134,6 +134,7 @@ export class AuthEffects {
@Effect({dispatch: false}) @Effect({dispatch: false})
public redirectToLogin: Observable<Action> = this.actions$ public redirectToLogin: Observable<Action> = this.actions$
.ofType(AuthActionTypes.REDIRECT_TOKEN_EXPIRED, AuthActionTypes.REDIRECT_AUTHENTICATION_REQUIRED) .ofType(AuthActionTypes.REDIRECT_TOKEN_EXPIRED, AuthActionTypes.REDIRECT_AUTHENTICATION_REQUIRED)
.do(() => this.authService.removeToken())
.do(() => this.authService.redirectToLogin()); .do(() => this.authService.redirectToLogin());
/** /**

View File

@@ -17,6 +17,7 @@ import { AuthTokenInfo } from './models/auth-token-info.model';
import { isNotEmpty, isUndefined } from '../../shared/empty.util'; import { isNotEmpty, isUndefined } from '../../shared/empty.util';
import { RedirectWhenTokenExpiredAction, RefreshTokenAction } from './auth.actions'; import { RedirectWhenTokenExpiredAction, RefreshTokenAction } from './auth.actions';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { Router } from '@angular/router';
@Injectable() @Injectable()
export class AuthInterceptor implements HttpInterceptor { export class AuthInterceptor implements HttpInterceptor {
@@ -26,7 +27,7 @@ export class AuthInterceptor implements HttpInterceptor {
// we're creating a refresh token request list // we're creating a refresh token request list
protected refreshTokenRequestUrls = []; protected refreshTokenRequestUrls = [];
constructor(private inj: Injector, private store: Store<AppState>) { } constructor(private inj: Injector, private router: Router, private store: Store<AppState>) { }
private isUnauthorized(response: HttpResponseBase): boolean { private isUnauthorized(response: HttpResponseBase): boolean {
// invalid_token The access token provided is expired, revoked, malformed, or invalid for other reasons // invalid_token The access token provided is expired, revoked, malformed, or invalid for other reasons
@@ -38,7 +39,7 @@ export class AuthInterceptor implements HttpInterceptor {
} }
private isAuthRequest(http: HttpRequest<any> | HttpResponseBase): boolean { private isAuthRequest(http: HttpRequest<any> | HttpResponseBase): boolean {
return http.url return http && http.url
&& (http.url.endsWith('/authn/login') && (http.url.endsWith('/authn/login')
|| http.url.endsWith('/authn/logout') || http.url.endsWith('/authn/logout')
|| http.url.endsWith('/authn/status')); || http.url.endsWith('/authn/status'));
@@ -71,10 +72,16 @@ export class AuthInterceptor implements HttpInterceptor {
const authService = this.inj.get(AuthService); const authService = this.inj.get(AuthService);
const token = authService.getToken(); const token = authService.getToken();
let newReq; let newReq;
if (authService.isTokenExpired()) {
authService.setRedirectUrl(this.router.url);
// The access token is expired
// Redirect to the login route
this.store.dispatch(new RedirectWhenTokenExpiredAction('Your session has expired. Please log in again.'));
return Observable.of(null);
} else if (!this.isAuthRequest(req) && isNotEmpty(token)) {
// Intercept a request that is not to the authentication endpoint // Intercept a request that is not to the authentication endpoint
if (!this.isAuthRequest(req) && isNotEmpty(token)) {
authService.isTokenExpiring() authService.isTokenExpiring()
.filter((isExpiring) => isExpiring) .filter((isExpiring) => isExpiring)
.subscribe(() => { .subscribe(() => {

View File

@@ -22,6 +22,8 @@ import { NativeWindowRef, NativeWindowService } from '../../shared/services/wind
export const LOGIN_ROUTE = '/login'; export const LOGIN_ROUTE = '/login';
export const REDIRECT_COOKIE = 'dsRedirectUrl';
/** /**
* The auth service. * The auth service.
*/ */
@@ -261,7 +263,8 @@ export class AuthService {
* Redirect to the login route * Redirect to the login route
*/ */
public redirectToLogin() { public redirectToLogin() {
this.router.navigate(['/login']); // Hard redirect to login page, so that all state is definitely lost
this._window.nativeWindow.location.href = LOGIN_ROUTE;
} }
/** /**
@@ -272,8 +275,10 @@ export class AuthService {
.first() .first()
.subscribe((redirectUrl) => { .subscribe((redirectUrl) => {
if (isNotEmpty(redirectUrl)) { if (isNotEmpty(redirectUrl)) {
// Clear url // Clear redirect url
this.setRedirectUrl(undefined); this.setRedirectUrl(undefined);
this.storage.remove(REDIRECT_COOKIE);
const urlTree: UrlTree = this.router.parseUrl(redirectUrl); const urlTree: UrlTree = this.router.parseUrl(redirectUrl);
const g: UrlSegmentGroup = urlTree.root.children[PRIMARY_OUTLET]; const g: UrlSegmentGroup = urlTree.root.children[PRIMARY_OUTLET];
const segment = '/' + g.toString(); const segment = '/' + g.toString();
@@ -283,7 +288,13 @@ export class AuthService {
}; };
this.router.navigate([segment], navigationExtras); this.router.navigate([segment], navigationExtras);
} else { } else {
this.router.navigate(['/']); // override the route reuse strategy
this.router.routeReuseStrategy.shouldReuseRoute = () => {
return false;
};
this.router.navigated = false;
const url = decodeURIComponent(this.router.url);
this.router.navigateByUrl(url);
} }
}) })
@@ -301,13 +312,19 @@ export class AuthService {
* Get redirect url * Get redirect url
*/ */
getRedirectUrl(): Observable<string> { getRedirectUrl(): Observable<string> {
const redirectUrl = this.storage.get(REDIRECT_COOKIE);
if (isNotEmpty(redirectUrl)) {
return Observable.of(redirectUrl);
} else {
return this.store.select(getRedirectUrl); return this.store.select(getRedirectUrl);
} }
}
/** /**
* Set redirect url * Set redirect url
*/ */
setRedirectUrl(url: string) { setRedirectUrl(url: string) {
this.storage.set(REDIRECT_COOKIE, url);
this.store.dispatch(new SetRedirectUrlAction(isNotUndefined(url) ? url : '')); this.store.dispatch(new SetRedirectUrlAction(isNotUndefined(url) ? url : ''));
} }
} }

View File

@@ -60,7 +60,6 @@ export class AuthenticatedGuard implements CanActivate, CanLoad {
.take(1) .take(1)
.subscribe((authenticated) => { .subscribe((authenticated) => {
if (!authenticated) { if (!authenticated) {
console.log('set redirect ', url);
this.authService.setRedirectUrl(url); this.authService.setRedirectUrl(url);
this.store.dispatch(new RedirectWhenAuthenticationIsRequiredAction('Login required')); this.store.dispatch(new RedirectWhenAuthenticationIsRequiredAction('Login required'));
} }