I'm using an HttpInterceptor to apply an access token to outgoing httprequests. The interceptor calls getUser() that returns Observable, adds the accesstoken to the requests. This all works fine and dandy. But what I now want is that if the requests returns 401, I want to refresh the token and then handle the request again. So I catch any errors, and call renewToken, which also returns Observable. But the problem is that it does not seem to access the callback function of renewToken. So the refreshed token never gets applied and the api call never gets reexecuted, however, the renewToken shows up in my network tab and that is successful.
I made sure that the renewToken() actually works by replacing the first getUser() call with renewToken(), and that works. So my guess is that my confusion with rxjs and how to chain long pipes etc is where this goes wrong.
intercept(
request: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
if (request.url.includes(environment.apiBaseUrl)) {
return this.authService.getUser().pipe(
mergeMap((user: User) => {
console.log('in getUser call ' + user.expires_in);
if (user) {
request = request.clone({
setHeaders: {
Authorization: `Bearer ${user.access_token}`
}
});
}
return next.handle(request).pipe(
tap(
() => {},
(err: any) => {
debugger
if (err instanceof HttpErrorResponse) {
if (err.status === 401) {
return this.authService.renewToken().pipe(
mergeMap((renewedUser: User) => {
console.log('in renewToken call');
if (renewedUser) {
console.log(renewedUser.expires_in);
request = request.clone({
setHeaders: {
Authorization: `Bearer ${
renewedUser.access_token
}`
}
});
}
return next.handle(request).pipe(
tap(
() => {},
newErr => {
console.log(newErr);
this.authService.login();
}
)
);
}),
catchError(renewError => {
return Observable.throw(renewError);
})
);
}
}
}
)
);
})
);
} else {
return next.handle(request);
}
}
So what I want is to refresh the token and redo the request if I'm unauthorized on the first request, but I never enter the callback-function of renewToken() to add the new accesstoken and redo the request.
Also, the ideal would be to use the expired-property on user and if it is expired then refresh the token and then handle the request just once, but I don't know how to achieve this asynchronously.
EDIT: I'm pretty sure that this has to do with the fact that I can't return something in the way that I think I can from the tap function. so when trying to return renewToken or next.handle that's just not possible. Nonetheless, I have no idea how to actually renew the token and redo the request with the new token if the first request returns an error