I am using Angular 2 with TypeScript on the front-end. I am trying to implement a http interceptor that is setting the authorization header on each request. If the access token expires I am trying to retry the request, get a new access token with the refresh token and change the header of the current request, before the retry.
How to update the request header in the retryWhen operator?
For example here is the HttpInterceptor:
export class HttpInterceptor extends Http {
get(url: string, options?: RequestOptionsArgs): Observable<Response> {
return super.get(url, this.setRequestAuthorizationHeader(options)).retryWhen((errors: any) => this.errorHandler(errors));
}
private setRequestAuthorizationHeader(options?: RequestOptionsArgs): RequestOptionsArgs {
// some checks
// get accessToken from localStorage
options.headers.append('Authorization', 'Bearer ' + accessToken);
}
private errorHandler(errors) {
return errors.switchMap((err) => {
if (err.status === 401) {
let closedSubject = new Subject();
this.authenticationService.refreshToken()
.subscribe(data => {
// How to update authorization header? This doesn't work.
this.defaultOptions.headers.append('Authorization', 'Bearer ' + data.accessToken);
closedSubject.next();
});
return <any>closedSubject;
}
else {
return Observable.throw(err.json());
}
});
}
}
I would use catch
instead of retryWhen
as the latter one replay the same observable, and the parameters have already been set.
BTW, your Subject is useless in errorHanlder
:
export class HttpInterceptor extends Http {
get(url: string, options ? : RequestOptionsArgs): Observable < Response > {
return super.get(url, this.setRequestAuthorizationHeader(options)).catch(errors => this.errorHandler(errors, url, options))
});
}
private setRequestAuthorizationHeader(options ? : RequestOptionsArgs): RequestOptionsArgs {
// some checks
// get accessToken from localStorage
options.headers.append('Authorization', 'Bearer ' + accessToken);
return options
}
private errorHandler(err: any, url: string, options ? : RequestOptionsArgs) {
if (err.status === 401) {
return this.authenticationService.refreshToken()
.switchMap(data => {
// save accessToken to localStorage
return super.get(url, this.setRequestAuthorizationHeader(options));
});
}
return Observable.throw(err.json());
}
Also note that using state like this.defaultOptions
is probably not your best choice, using anobservable would be more appropriate.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With