All of the examples that I'm following (https://github.com/bartosz-io/jwt-auth-angular), do not have a subscribe in the code, but it is the only way I can get my interceptor function to work. Notice my subscribe() calls. It seems as though I'm not returning something properly, because the code examples do not show that I need to subscribe. I know what subscribe does for an Observable, but shouldn't the interceptor be part of the http calling function subscription?
import {
HttpEvent,
HttpInterceptor,
HttpHandler,
HttpRequest,
HttpResponse,
HttpErrorResponse
} from "@angular/common/http";
import { Injectable } from "@angular/core";
import { BehaviorSubject, Observable, of } from "rxjs";
import { switchMap, filter, take, tap, catchError, mergeMap } from 'rxjs/operators';
import { AuthService } from "./auth.service";
import { MyHttpGetService } from "./http.service";
import { iToken } from "../../interfaces/token.interface";
@Injectable()
export class AddHeaderInterceptor implements HttpInterceptor {
private isRefreshing = false;
private refreshTokenSubject: BehaviorSubject<any> = new BehaviorSubject<any>(null);
private requestArray = [];
constructor(
private authenticationService: AuthService,
private httpApiService: MyHttpGetService,
) { }
intercept(
request: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
this.refreshTokenSubject.next(null);
const authToken = this.authenticationService.getToken();
request = this.addToken(request, authToken);
return next.handle(request).pipe(
catchError(async (err: HttpErrorResponse) => {
if (
[401, 403].includes(err.status) &&
!request.url.includes("GetRefreshToken")
) {
console.log('retry here', request);
return this.handle401Error(request, next);
} else {
next.handle(request);
}
}
)
) as Observable<HttpEvent<any>>;
}
private addToken(request: HttpRequest<any>, authToken: iToken) {
return request.clone({
setHeaders: {
"Content-Type": "application/json",
Authorization: `Bearer ${authToken.accessToken}`,
},
})
}
private async handle401Error(request: HttpRequest<any>, next: HttpHandler) {
const currToken = this.authenticationService.getToken();
if (!this.isRefreshing) {
this.isRefreshing = true;
this.refreshTokenSubject.next(null);
return this.httpApiService.getAccessToken(currToken).pipe(
tap((response: any) => {
this.authenticationService.setAccessToken(response.body);
}),
switchMap((res) => {
this.isRefreshing = false;
this.refreshTokenSubject.next(res.body);
return next.handle(this.addToken(request, res.body));
})).subscribe();
} else {
return this.refreshTokenSubject.pipe(
tap((token) => console.log('refreshToken else', token)),
filter(token => token != null),
take(1),
switchMap(token => {
return next.handle(this.addToken(request, token));
})).subscribe();
}
}
}