I'm using Angular 13.
Currently my error.interceptor it automatically catches the 401 error and automatically refreshes the jwt token.
In addition to this, I would need the error.interceptor try to make the previously intercepted call just after the subscribed "validateNewToken()".
Below is an example of my error.interceptor and the auth.interceptor:
error.interceptor
@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
constructor(private authService: AuthService, private router: Router, private toastr: ToastrService) {
}
intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
return next.handle(request)
.pipe(catchError((err: HttpErrorResponse) => {
console.error('Error Intercepted', err)
if(err.error.code == '40102' || err.error.error == 'unauthorized_client'){
this.authService.refreshToken().subscribe((res ) => {
localStorage.setItem('access_token', res.access_token);
this.authService.validateNewToken(res.access_token).subscribe((resVer: any) => {
localStorage.setItem('username', resVer.sub);
})
})
}
return throwError(() => err);
}));
}
}
auth.interceptor
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor(private authService: AuthService) { }
intercept(req: HttpRequest<any>, next: HttpHandler) {
const authToken = this.authService.getToken();
const username = localStorage.getItem('username');
if (authToken && username) {
req = req.clone({
setHeaders: {
'Authorization': `Bearer ${authToken}`,
'OAM_REMOTE_USER': username,
'rejectUnauthorized' : 'false'
}
})
}
return next.handle(req)
}
}
Thanks in advance
CodePudding user response:
MY SOLUTION EDIT error.interceptor:
@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
constructor(private authService: AuthService, private router: Router, private toastr: ToastrService) {
}
private isRefreshing = false;
private refreshTokenSubject: BehaviorSubject<any> = new BehaviorSubject<any>(null);
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<Object>> {
let authReq = req;
const token = this.authService.getToken();
const authToken = this.authService.getToken();
const username = localStorage.getItem('username');
if (token != null) {
authReq = this.addTokenHeader(req);
}
return next.handle(authReq).pipe(catchError(error => {
if (error instanceof HttpErrorResponse && (error.error.code == '40102' || error.error.error == 'unauthorized_client')) {
return this.handle401Error(authReq, next);
}
return throwError(() => error);
}));
}
private handle401Error(request: HttpRequest<any>, next: HttpHandler) {
if (!this.isRefreshing) {
this.isRefreshing = true;
this.refreshTokenSubject.next(null);
return this.authService.refreshToken().pipe(
switchMap((res: any) => {
localStorage.setItem('access_token', res.access_token);
this.authService.verifyToken(res.access_token).subscribe((resVer: any) => {
localStorage.setItem('username', resVer.sub);
this.isRefreshing = false;
this.refreshTokenSubject.next(res.access_token);
})
return next.handle(this.addTokenHeader(request));
}),
catchError((err) => {
this.isRefreshing = false;
return throwError(() => err);
})
);
}
return this.refreshTokenSubject.pipe(
filter(token => token !== null),
take(1),
switchMap((token) => next.handle(this.addTokenHeader(request)))
);
}
private addTokenHeader(request: HttpRequest<any>) {
const authToken = this.authService.getToken();
const username = localStorage.getItem('username');
if (authToken && username) {
return request = request.clone({
setHeaders: {
'Authorization': `Bearer ${authToken}`,
'OAM_REMOTE_USER': username,
'rejectUnauthorized': 'false'
}
})
} else {
return request;
}
}
}