angularangular-http-interceptors

Angular 17 - HttpInterceptorFn - Queue http requests while renew token service is not finished


In an Angular 17 project, with HttpInterceptorFn, I meet a concern when renewing an authentication token. Indeed, when two requests arrive while the two have an expired token, two renewal requests are then launched. The concern is that the second fails because the renewal token was modified by the second. So I have the idea of setting up a waiting line that would take the requests occurring during a current token renewal. But I do not see how to then manage the execution of the requests contained in the waiting line. Do you have an idea of how I could manage this case ? Thanks !

In an Angular 17 project, with HttpInterceptorFn, I wish to put HTTP requests in waiting lines while a Token renewal request is underway, and then executed the requests in waiting lines.


Solution

  • You should keep the state of refreshtoken request pending for example using subject that will emit once refresh is completed and then for any next request when you catch 401 and see that subject exists (which means refresh is pending) then just wait for it and retry after completed:

    let refreshingToken$: Subject<void> | null = null;
    
    export const refreshTokenInterceptor: HttpInterceptorFn = (
      req: HttpRequest<unknown>,
      next: HttpHandlerFn
    ) => {
      const http = inject(HttpClient);
    
      return next(req).pipe(
        catchError((err) => {
          if (err.status === 401) {
            if (!refreshingToken$) {
              refreshingToken$ = new Subject<void>();
              http.get('/refresh').subscribe(() => {
                refreshingToken$!.next();
                refreshingToken$!.complete();
                refreshingToken$ = null;
              });
            }
            return refreshingToken$.pipe(switchMap(() => next(req)));
          }
    
          throw err;
        })
      );
    };