-1

I'm trying to make an interceptor to refresh the user token if there is an authentication error. I'm asking this here because even with some tutorials and other questions I can't make mine works.

Here is my intercept function :

public intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
console.log('===== Intercept =====');
console.log(req);
return next.handle(req).pipe(
  catchError((err: any) => {
    console.log(err);

    this.refreshToken().subscribe( resolve => {
      console.log('RESOLVE');
      // clone the original request
      if (resolve) {

        console.log('REQ REPEAT');

        let headers = new HttpHeaders({
          'Content-Type': 'application/json'
        });
        if (this.appState.token !== null) {
          headers = headers.set('Authorization', 'Bearer ' + this.appState.token);
        }

        const authReqRepeat = req.clone(
          {headers: headers}
        );


        console.log('NEW TOKEN : Bearer ' + this.appState.token);
        console.log(authReqRepeat);
        // resend the request
        return next.handle(authReqRepeat);
      } else {
        return next.handle(req);
      }
    }, error => {
      console.log('ERROR');
      return throwError(error);
    });
  }),
);
}

The refreshToken function returns me a true or false answer (true if the refresh is OK).

So my first problem is about the clone request headers, I tried multiple possibilites to put them but at the end there is still no header on my cloned request (there are the original request header if I don't try to add a new one).

Next problem is also about the request, when it comes to the next.handle with my new request isn't send (I don't have any log about this request), and nothing is returned to my app so my component are waiting for an answer that will never come.

And the third problem is about the catchError, I have this error in the (err : any)

TS2345: Argument of type '(err: any) => void' is not assignable to parameter of type '(err: any, caught: Observable<HttpEvent<any>>) => ObservableInput<{}>'.   Type 'void' is not assignable to type 'ObservableInput<{}>'.

I'm not really comfortable with the observable, but if I add a return throwError(error); after my call to refreshToken the error disapear, but I have an infinite loop.

Jess
  • 21
  • 5

1 Answers1

0

the first Question, try to use this instead of set of append:

const headers = new HttpHeaders({
                'Content-Type': 'application/json',
                'Authorization': 'Bearer ' + this.appState.token
              });

the second Question, because you only use next.handle(authReqRepeat). and no subscriber, so it can't run, you can try this:

http.request(authReqRepeat).subscribe(()=>{})

the last Question, using error inside of a 'tap' pipe observable :

next.handle(req).pipe(
        tap((res) => return of(res),(error) => {doSomething(error); return of(error)})
      );

as for infinite loop, it is because you repeatedly handle the request with the same process which is intercepted by self, so try some ways to jump the inner request like this:

if (this.reqList.indexOf(req)){ return handle.next(req)} and then ...
Coco
  • 457
  • 1
  • 3
  • 14