2

I have a basic JWT system, and an Interceptor that checks whether the request fails due to being unauthorized.

import {Injectable} from '@angular/core';
import {HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from '@angular/common/http';
import {Observable, throwError} from 'rxjs';
import {AuthService} from '../services/auth.service';
import {catchError, retryWhen} from 'rxjs/operators';

@Injectable()
export class AuthenticationErrorInterceptor implements HttpInterceptor {

  private readonly _authService: AuthService;

  constructor(authService: AuthService) {
    this._authService = authService;
  }

  public intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const authReq = req.clone({headers: req.headers});
    return next.handle(authReq)
      .pipe(
        catchError((err) => this._handleAuthError(err)),
        retry(3)
      );
  }

  private _handleAuthError(error: HttpErrorResponse): Observable<any> {
    if (error.status === 401 || error.status === 403) {
      return this._authService.authenticate();
    }

    return throwError(error);
  }
}

If the request does fail then I want to resend the request after I have called this._authService.authenticate();. It will reauthenticate, due to the error handling forcing it to reauthenticate but then it doesn't recall the request causing the app to fail until I refresh the browser.

How can I get my guard to try the request again?

I've tried using retryWhen as well but I get the same/similar result.

1 Answer 1

3

Call .next on the HTTP handler after you have re-authenticated your session. Ideally, you should return an authentication token from your authenticate method that can then be appended onto the request auth headers.

import {Injectable} from '@angular/core';
import {HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from '@angular/common/http';
import {Observable, throwError} from 'rxjs';
import {AuthService} from '../services/auth.service';
import {catchError, retryWhen} from 'rxjs/operators';

@Injectable()
export class AuthenticationErrorInterceptor implements HttpInterceptor {

  private readonly _authService: AuthService;

  constructor(authService: AuthService) {
    this._authService = authService;
  }

  public intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
      return next.handle(req)
            .pipe(
                catchError((error: HttpErrorResponse) => {
                  if (error.status === 401 || error.status === 403) {
                    return this._authService.authenticate()
                      .pipe(
                        mergeMap((token) => next.handle(req.clone({
                                    headers: req.headers.set(AUTH_TOKEN_NAME_HERE, token)
                                })))
                      );
                  }

                    return throwError(error);
                })
            );
  }
}
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.