2
votes

I am looking for a way to re-call the current request after refreshing a token within a 200 HttpReponse message. I have an error catch to handle a 401, but there are cases when a user will be "Unauthenticated" and that status will be returned in a 200 Response. This of course never falls into the Error Catch. I have the code below which fetches the new access_token and builds new "cloned" request with the token header, but then when calling

next.handle(newReq)

it does nothing. If I refresh the page it makes the request and all works, but I want it to complete the request with the NEW token from within the HttpResponse. Can someone point me in the right direction?

addToken(req: HttpRequest<any>, token: string): HttpRequest<any> {
    return req.clone({ setHeaders: { Authorization: 'Bearer ' + token }})
}

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpSentEvent | HttpHeaderResponse | HttpProgressEvent | HttpResponse<any> | HttpUserEvent<any>> {
    return next.handle(this.addToken(req, window.sessionStorage.getItem('access_token'))).pipe(map((event:any) => {
        if (event instanceof HttpResponse) {
            console.log('event--->>>', event);
            if(event.body && event.body.StatusCode == "Unauthenticated"){
            this.accSvc.RefreshAccessToken().subscribe((response:any) => {
                console.log(response);
                    console.log("Old Token: " + this.oldToken);
                    this.usrSvc.SetSessionTokensAndTime(response.access_token, response.refresh_token, response.expires_in);
                    var tok = window.sessionStorage.getItem("access_token");
                    console.log("New Token: " + tok);
                    var newReq = this.addToken(req, tok);
                    return next.handle(newReq); //THIS SHOWS THE 'newReq' has the NEW TOKEN, but when stepping over this in debug, it does nothing until page refreshed.

            })
            }
        }
        return event;
    })).pipe(
        catchError((error: HttpErrorResponse):any => {
            if(error instanceof HttpErrorResponse){
                switch ((<HttpErrorResponse>error).status) {
                    case 401:
                        return this.handle401Error(req, next);
                }
            } else {
                return throwError(error);
            }

          })
    )
}
1

1 Answers

0
votes

For those who are trying to do this, from what I have researched and tried, in order for the interceptor to handle the request using next.handle(req) in the case of "Unauthorized" it must be dealing with a 401. We had to change our api to return the 401 vs 200 with Unauthorized StatusCode. At that point, the interceptor worked as designed in the case of 401(Unauthorized).

My thought is that you cannot finalize the middleware, executing the final call and queue subsequent calls from within an HttpReponse event.

If you have control over your API, Update to return the 401.