Pranav Barot
Pranav Barot

Reputation: 62

After refreshing the token, the existing request to the original API replace with the /refersh-token API so I need to double check on button for data

When the token gets expired next: HttpHandler handle the request that comes from the server when it go inside the refershToken Subscribe method it goes to the header that I defined above the next.handle(request) and again comes to the next.handle(request) so my previous request go to the client and didn't update with the refresh token and now my existing request is /refersh-token. so after updating the token I need to double check on the button for the records or reload the page for the records.


// add authorization header with jwt token if available

refreshToken is API configuration in authenticationService class

refreshToken() {
  return this.http.get<CommonResponse>(`${environment.apiUrl}/refresh-token`);
}

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

const currentUser = this.authenticationService.currentUserValue;
if (currentUser?.token && 
  !environment.publicURLS.includes(request.url.replace(environment.apiUrl, "")) 
  && !this.router.url.includes("https://www.google.com/inputtools/request")) {
  request = request.clone({
    setHeaders: {
      Authorization: `Bearer ${currentUser.token}`,
    },
  });
}


return next.handle(request).pipe(tap((data: any) => {
      if (data.body?.body) {
        if (data.body.body.isTokenExpired) {
          this.authenticationService.refreshToken().pipe(map((res) => {
            return res;
          })).subscribe(res => {
            if (res?.body && !res?.isError && res?.body?.token) {
              const currentUser = this.authenticationService.currentUserValue;
              if (currentUser) {
                currentUser.token = res.body.token;
                localStorage.setItem('currentUser', JSON.stringify(currentUser));
                this.authenticationService.currentUserValueSubject.next(currentUser);
                const retryRequest = request.clone({
                  setHeaders: {
                    Authorization: 'Bearer ' + currentUser.token,
                  },
                });
                next.handle(retryRequest);
              }
            }
          }
          );
        }
        if (data.body.body.isTokenInvalid) {
          this.authenticationService.logout();
        }
      }
    }
    ));
  }

Upvotes: 2

Views: 62

Answers (1)

Jayesh Solanki
Jayesh Solanki

Reputation: 111

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const currentUser = this.authenticationService.currentUserValue;

    if (currentUser?.token && !environment.publicURLS.includes(request.url.replace(environment.apiUrl, '')) && !this.router.url.includes('https://www.google.com/inputtools/request')) {
      request = this.addTokenToHeader(request, currentUser.token);
    }

    return next.handle(request).pipe(
      mergeMap((data: HttpEvent<any>) => {
        if (data instanceof HttpResponse && data.body?.body) {
          if (data.body?.body?.isTokenExpired) {
            return this.handleTokenRefresh(request, next);
          }

          if (data.body?.body?.isTokenInvalid || data.body?.body?.isAccessDenied) {
            this.authenticationService.logout();
          }
        }

        return of(data);
      }),
      catchError((error) => {
        console.error('Error handling request:', error);
        return throwError(() => error);
      })
    );
  }

  private addTokenToHeader(request: HttpRequest<any>, token: string) {
    return request.clone({
      setHeaders: {
        Authorization: `Bearer ${token}`,
      },
    });
  }

  private handleTokenRefresh(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    if (!this.isRefreshing) {
      this.isRefreshing = true;
      this.refreshTokenSubject.next(null);

      return this.authenticationService.refreshToken().pipe(
        switchMap((res) => {
          if (res?.body && !res?.isError && res?.body?.token) {
            const newToken = res.body.token;
            const currentUser = this.authenticationService.currentUserValue;

            if (currentUser) {
              currentUser.token = newToken;
              localStorage.setItem('currentUser', JSON.stringify(currentUser));
              this.authenticationService.currentUserValueSubject.next(currentUser);
            }

            this.refreshTokenSubject.next(newToken);
            return next.handle(this.addTokenToHeader(request, newToken));
          }
          return throwError(() => 'Refresh token failed');
        }),
        catchError((err) => {
          return throwError(() => err);
        }),
        finalize(() => {
          this.isRefreshing = false;
        })
      );
    } else {
      return this.refreshTokenSubject.pipe(
        filter((token) => token != null),
        take(1),
        switchMap((token) => next.handle(this.addTokenToHeader(request, token!)))
      );
    }
  }

Upvotes: 1

Related Questions