Search code examples
angularpromiseamazon-cognitoangular-http-interceptors

How to add AWS Cognito token to the Angular Http Interceptor


I am building a login page for my application with AWS Cognito and Angular 8. Everything works fine until I try to create getToken() function, it turns out that the getSession() method accept a callback instead of returning a string.

Which mean I have to wrap it inside a Promise like this:

export function getToken() {
  var currentUser = userPool.getCurrentUser();
  if (!currentUser) {
    // redirect to login page
  } else {
    return new Promise((resolve, reject) => {
      currentUser.getSession((err, session) => {
        if (err) {
          reject(err);
        } else if (!session.isValid()) {
          resolve(null);
        } else {
          resolve(session.getIdToken().getJwtToken());
        }
      });
    });
  }
}

And here my interceptor:

@Injectable()
export class AuthenInterceptor implements HttpInterceptor {

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

        // Add token to the header.......

        return next.handle(req);
    }
}

As far as I can tell, returning a Promise here is not an option. So how can I add the token to the header? Or should I fetch it directly from the localStorage?


Solution

  • You can return an Observable in the intercept function. return next.handle(req); is returning an Observable<HttpEvent<any>>.

    You can return an Observable from getToken() with from:

    import { from } from 'rxjs';
    
    export function getToken() {
      var currentUser = userPool.getCurrentUser();
      if (!currentUser) {
        // redirect to login page
      } else {
        return from(
          new Promise((resolve, reject) => {
            currentUser.getSession((err, session) => {
              if (err) {
                reject(err);
              } else if (!session.isValid()) {
                resolve(null);
              } else {
              resolve(session.getIdToken().getJwtToken());
              }
            });
          });
        );
      }
    }
    

    And then use it in intercept with mergeMap:

    import { mergeMap } from 'rxjs/operators';
    
    return getToken().pipe(
      mergeMap((token) =>
      {
        request = request.clone(
        {
            setHeaders : { ... }
        });
    
        return next.handle(request);
      })
    )