import { Injectable } from '@angular/core'; import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor, HttpErrorResponse } from '@angular/common/http'; import { AuthService } from '@app/services/auth2.service'; import { Observable, throwError, BehaviorSubject } from 'rxjs'; import { catchError, filter, take, switchMap } from 'rxjs/operators'; @Injectable() export class TokenInterceptor implements HttpInterceptor { private isRefreshing = false; private refreshTokenSubject: BehaviorSubject = new BehaviorSubject(null); constructor(public authService: AuthService) { } intercept(request: HttpRequest, next: HttpHandler): Observable> { if (request.url.indexOf("auth/refresh")!= -1){ request = this.addToken(request, this.authService.getRefreshToken()); } else if (request.url.indexOf("openweather")!= -1){ request; } else { if (this.authService.getJwtToken()) { request = this.addToken(request, this.authService.getJwtToken()); } } return next.handle(request).pipe(catchError(error => { if (error instanceof HttpErrorResponse && error.status === 401) { return this.handle401Error(request, next); } else { return throwError(error); } })); } private addToken(request: HttpRequest, token: string) { return request.clone({ setHeaders: { 'Authorization': `Bearer ${token}` } }); } private handle401Error(request: HttpRequest, next: HttpHandler) { if (!this.isRefreshing) { this.isRefreshing = true; this.refreshTokenSubject.next(null); return this.authService.refreshToken().pipe( switchMap((token: any) => { this.isRefreshing = false; this.refreshTokenSubject.next(token["data"]["access_token"]); return next.handle(this.addToken(request, token["data"]["access_token"])); })); } else { return this.refreshTokenSubject.pipe( filter(token => token != null), take(1), switchMap(jwt => { return next.handle(this.addToken(request, jwt)); })); } } }