#Interceptor using wrong token as authorization headers

6 messages · Page 1 of 1 (latest)

clever moon
#

Hello, i'm having issues with my interceptor :
when making a post request to the refresh token route it's sending the access token as header while it should use the refresh token.

Here's the context :

  • the interceptor will add access token to every jwt protected routes
  • if access token is expired, the api will send a 498 code error
  • when we receive a 498 we will make a post request to the refresh route with refresh token as authorization headers and access token in the body
  • the refresh route will return an object containing the new access token
  • sending the initial request again

=> the api route works fine with the correct headers and body ( getting a new access token as expected)

#

Interceptor :


  intercept<T>(request: HttpRequest<T>, next: HttpHandler): Observable<HttpEvent<T>> {
    // Jwt route
    if (this._token_service.get_access_token() !== undefined) {
      request = this._add_token_header(request, this._token_service.get_access_token() ?? '');
    }

    return next.handle(request).pipe(
      catchError(error => {
        // Expired jwt
        if (error instanceof HttpErrorResponse && error.status === 498) {
          return this._handle_498(request, next);
        }
        // Other error
        else {
          return throwError(error);
        }
      })
    );
  }
  // Add token to request headers
  private _add_token_header<T>(request: HttpRequest<T>, token: string): HttpRequest<T> {
    return request.clone({
      setHeaders: { Authorization: 'Bearer ' + token },
    });
  }

  // Refresh token
  private _handle_498<T>(request: HttpRequest<T>, next: HttpHandler): Observable<HttpEvent<T>> {
    if (!this.is_refreshing) {
      this.is_refreshing = true;
      this.refreshTokenSubject.next(null);

      return this._auth_service.generate_refresh_token().pipe(
        switchMap((res: RefreshTokenResponse) => {
          this.is_refreshing = false;
          this.refreshTokenSubject.next(res.access_token);
          return next.handle(this._add_token_header(request, res.access_token));
        })
      );
    } else {
      return this.refreshTokenSubject.pipe(
        filter(token => token !== null),
        take(1),
        switchMap(res => {
          return next.handle(this._add_token_header(request, res.access_token));
        })
      );
    }
  }
#

Service :

  generate_refresh_token(): Observable<RefreshTokenResponse> {
    return this._http.post<RefreshTokenResponse>(
      `${AUTH_URL}refresh`,
      { access_token: this._token_service.get_access_token() },
      {
        headers: { Authorization: 'Bearer ' + this._token_service.get_refresh_token() },
      }
    );
  }
sand jasper
#

It looks like you are explicitly adding the access token as header in all cases in the interceptor, so it's most likely overwriting the header set in the service to call the refresh endpoint.

#

That said, i am not sure why you want to send the refresh token as an authorization header in the first place, that's not the intention of that header.

#

Personally i would stick to OAuth, or even better, rely on existing tools that solve it for you.