Angular interceptor should use token and later refreshed token

42 Views Asked by At

I have an Angular project where I want to use a token. After about 1/2 hour, the interceptor should call a refresh endpoint and get a new token. But I am having trouple getting it to work.

import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { SapToken } from './sapToken.service';
import { switchMap } from 'rxjs/operators';
import { ISapToken } from './model';

// A global interceptor to handle language on http calls
@Injectable()
export class SapTokenInterceptor implements HttpInterceptor {
  constructor(
    private _sapToken: SapToken
  ) { }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    let headers = req.headers
    if (this._sapToken.sapToken.value) {
      headers = req.headers
        .set('X-SAPAccessToken', this._sapToken.sapToken.value.accessToken);
    }

    const copiedReq = req.clone({ headers });
    return next.handle(copiedReq).pipe(switchMap(() => {
      if (this._sapToken.sapToken.value) {
        const time = this._sapToken.expireDuration(this._sapToken.sapToken.value.expires);
        console.log('refresh token');
        if (time <= 0) {
          console.log('less', time)
          this._sapToken.refreshSapSessionToken().subscribe((refreshedToken: ISapToken) => {
            this._sapToken.sapToken.next(refreshedToken);
            headers = req.headers
              .set('X-SAPAccessToken', refreshedToken.accessToken);

            const copiedReq = req.clone({ headers });
            return next.handle(copiedReq);
          })
        }
      }

      return next.handle(copiedReq);
    }));
  }
}
1

There are 1 best solutions below

0
Johansrk On

ok I seem to have fixed it myself

import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { SapToken } from './sapToken.service';
import { switchMap } from 'rxjs/operators';
import { ISapToken } from './model';

// A global interceptor to handle language on http calls
@Injectable()
export class SapTokenInterceptor implements HttpInterceptor {
  private refreshTokenInProgress = false;
  constructor(
    private _sapToken: SapToken
  ) { }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    let headers = req.headers
    if (this._sapToken.sapToken.value) {
      headers = req.headers
        .set('X-SAPAccessToken', this._sapToken.sapToken.value.accessToken);
    }

    const copiedReq = req.clone({ headers });
    if (this._sapToken.sapToken.value) {
      const time = this._sapToken.expireDuration(this._sapToken.sapToken.value.expires);
      if (time <= 0 && !this.refreshTokenInProgress) {
        this.refreshTokenInProgress = true;
        return this._sapToken.refreshSapSessionToken().pipe(switchMap((refreshedToken: ISapToken) => {
          this._sapToken.sapToken.next(refreshedToken);
          headers = req.headers
            .set('X-SAPAccessToken', refreshedToken.accessToken);

          const copiedReq = req.clone({ headers });
          this.refreshTokenInProgress = false;
          return next.handle(copiedReq);
        }));
      }
    }
    return next.handle(copiedReq);
  }
}