0
votes

I use ngrx to store my session infos (the token itself and it's expiration date). There are two interceptors in the http pipeline: interceptor 1 injects the token from the store to the http request, interceptor 2 reads a custom http header "X-Session-Expiration" from the response and places it in the store (I also had both actions in one interceptor, didn't solve the problem either).

intercept(request: HttpRequest, next: HttpHandler): Observable> {

    return this.store.select(SessionSelectors.sessionToken).pipe(
      first(),
      mergeMap(token => {
        console.log("interceptor 1");

        if (token) {
          request = request.clone({ headers: request.headers.set('Authorization', 'User ' + token) });
        }

        return next.handle(request);
      })
    );
}
intercept(request: HttpRequest, next: HttpHandler):  Observable> {

    return next.handle(request).pipe(map((event: HttpEvent) => {
      if (event instanceof HttpResponse) {
        console.log("interceptor 2");

        if (event.headers.has("X-Session-Expiration")) {
          var value = event.headers.get("X-Session-Expiration");
          var expiration = new Date(value);

          this.store.dispatch(new SessionActions.RefreshSessionExpiration({ newExpirationDate: expiration }));
      }

      return event;
    }));
}

This creates an infinite loop. The store modification in interceptor 2 triggers the subscription in interceptor 1, which fires the http request which triggers interceptor 2 and so on.

To prevent this I inserted first() or take(1) in interceptor 1, but it doesn't seem to change anything.

1
have you tried using switchMap instead of mergeMap in your first interceptor?dee zg
Thanks for the answer, yes I tried switchMap, mergeMap and flatMap. No changeAlex

1 Answers

0
votes

Try to add if statement in the begin of your interceptor

intercept(request: HttpRequest, next: HttpHandler): Observable> {
if (request.url === 'api/refresh-token') {
    return next.handle(request);
}

 return this.store.select(SessionSelectors.sessionToken).pipe(
    mergeMap(token => {
      .....
    }

    return next.handle(requestWithToken);
  })
 );
}