I'm trying to write HttpInterceptor that is refreshing the API access token when it's near it's expiration.
The main problem is to hold any HTTP request before the refresh token request comes back. If the token was refreshed successfully, the given request can fire and if not, the application should do the auto logout.
In short:
- I have 2 Observables
- I want to subscribe to the first one (refresh token)
- if this succeeds, I want to return the second observable (request from method params)
- if not, I want to auto-logout and throw an Observable
Here is my current code:
@Injectable()
export class RefreshTokenInterceptor implements HttpInterceptor {
constructor(private authenticationService: AuthenticationService) { }
public intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (this.isRefreshOfAccessTokenUnnecessary()) {
return next.handle(request);
}
return this.authenticationService.refreshToken()
.concatMap(() => next.handle(request))
.filter((item) => item instanceof HttpResponse)
.catch(() => this.refreshTokenFail());
}
private isRefreshOfAccessTokenUnnecessary(): boolean {
...
}
private refreshTokenFail(): ErrorObservable {
this.authenticationService.logOut();
return Observable.throw(new Error('not authorized'));
}
}
The thing is that I have troubles with using the appropriate Observable operator for that. concatMap seems to work, but it's not perfect. The token refresh happens without problems, the other requests are waiting, but this results in duplicated requests sometimes.
Can someone point me which operator from RxJS would be appropriate here? The documentation is not very helpful to be honest.
I'm not using lettable operators from RxJS yet.