diff --git a/frontend/src/app/app.module.ts b/frontend/src/app/app.module.ts index e3e2fee..7ff4aeb 100644 --- a/frontend/src/app/app.module.ts +++ b/frontend/src/app/app.module.ts @@ -4,7 +4,7 @@ import {NgModule} from '@angular/core'; import {AppRoutingModule} from './app-routing.module'; import {LandingComponent} from './component/landing/landing.component'; import {RestService} from './services/rest.service'; -import {HttpClientModule} from '@angular/common/http'; +import {HTTP_INTERCEPTORS, HttpClientModule} from '@angular/common/http'; import {LoggerModule, NgxLoggerLevel} from 'ngx-logger'; import {environment} from '../environments/environment'; import {FormsModule, ReactiveFormsModule} from '@angular/forms'; @@ -30,6 +30,7 @@ import { EditierenComponent } from './component/einstellungen/editieren/editiere import {MaterialFileInputModule} from 'ngx-material-file-input'; import { DialogComponent } from './component/dialog/dialog.component'; import {MatDialogModule} from '@angular/material/dialog'; +import {InterceptorService} from './services/interceptor.service'; @NgModule({ declarations: [LandingComponent, LoginComponent, NavigationComponent, @@ -61,9 +62,9 @@ import {MatDialogModule} from '@angular/material/dialog'; AuthGuardService, RestService, JwtHelper, - /*{ + { provide: HTTP_INTERCEPTORS, useClass: InterceptorService, multi: true - },*/ + }, ], bootstrap: [LandingComponent] diff --git a/frontend/src/app/services/auth.service.ts b/frontend/src/app/services/auth.service.ts index b67e200..2c249b4 100644 --- a/frontend/src/app/services/auth.service.ts +++ b/frontend/src/app/services/auth.service.ts @@ -27,12 +27,18 @@ export class AuthService { return sessionStorage.getItem(this.tokenKey); } - // Check whether the token is expired and return - // true or false + /** + * Check whether the token is expired and return true or false + * If false, removes token from sessionStorage. + */ public isAuthenticated(): boolean { const token = sessionStorage.getItem(this.tokenKey); if (token) { - return !this.jwtHelper.isTokenExpired(token); + const authenticated = !this.jwtHelper.isTokenExpired(token); + if (!authenticated) { + sessionStorage.removeItem(this.tokenKey); + } + return authenticated; } else { return false; } diff --git a/frontend/src/app/services/interceptor.service.ts b/frontend/src/app/services/interceptor.service.ts index dde8151..73958d5 100644 --- a/frontend/src/app/services/interceptor.service.ts +++ b/frontend/src/app/services/interceptor.service.ts @@ -1,9 +1,9 @@ -import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse} from '@angular/common/http'; +import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from '@angular/common/http'; import {Injectable} from '@angular/core'; import {Observable} from 'rxjs'; -import {tap} from 'rxjs/operators'; import {NGXLogger} from 'ngx-logger'; import {AuthService} from './auth.service'; +import {Router} from '@angular/router'; @Injectable({ providedIn: 'root' @@ -13,41 +13,28 @@ import {AuthService} from './auth.service'; */ export class InterceptorService implements HttpInterceptor { - constructor(private logger: NGXLogger, private authService: AuthService) { + constructor(private logger: NGXLogger, + private authService: AuthService, + private router: Router + ) { } /** - * Intercepts every HTTP request and for example adds a token + * Intercepts every HTTP request. + * If the token is invalid (expired) the user is redirected to logout (always). * @param req http request * @param next http response handler */ intercept(req: HttpRequest, next: HttpHandler): Observable> { + // FOR TESTING ONLY - sets an expired token + // sessionStorage.setItem('loginToken', 'eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MTk4ODYzNTF9.e83okQ1NHjeO-AxaB3SQP9P5UjOYy-e5DFissDdf2Mo'); - const token = this.authService.getToken(); - - // the original request is immutable, so we need to clone it - req = req.clone({ - setHeaders: { - // FIXME e.g. if Bearer is used - Authorization: `Bearer ${token}` - } - }); - - this.logger.debug('Interceptor works'); - - // pipe the response observable - return next.handle(req).pipe( - // perform a side effect for every emission on the source Observable - // return an Observable that is identical to the source - tap(event => { - // check if it is the response message - if (event instanceof HttpResponse) { - // TODO so something if necessary - } - }, error => { - // TODO handle error here - this.logger.error('HTTP Response interception error', error); - }) - ); + const authenticated = this.authService.isAuthenticated(); + this.logger.debug('isAuthenticated?', authenticated); + if (!this.authService.isAuthenticated()) { + this.logger.debug('token invalid, route to login'); + this.router.navigate(['login']).then(() => {}); + } + return next.handle(req); } }