mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-08 02:24:11 +00:00
Added redirect to login whether token is expired
This commit is contained in:
@@ -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());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -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;
|
||||||
// Intercept a request that is not to the authentication endpoint
|
|
||||||
if (!this.isAuthRequest(req) && isNotEmpty(token)) {
|
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
|
||||||
authService.isTokenExpiring()
|
authService.isTokenExpiring()
|
||||||
.filter((isExpiring) => isExpiring)
|
.filter((isExpiring) => isExpiring)
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
|
@@ -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> {
|
||||||
return this.store.select(getRedirectUrl);
|
const redirectUrl = this.storage.get(REDIRECT_COOKIE);
|
||||||
|
if (isNotEmpty(redirectUrl)) {
|
||||||
|
return Observable.of(redirectUrl);
|
||||||
|
} else {
|
||||||
|
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 : ''));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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'));
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user