Blog>
Snippets

Handling CSRF Token Mismatch Error in Angular

Present an example of how to handle CSRF token mismatch errors and reattempt the request in Angular using the catchError operator from RxJS.
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpErrorResponse } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError, switchMap } from 'rxjs/operators';

@Injectable()
export class CsrfInterceptor implements HttpInterceptor {
  constructor(private authService: AuthService) {} // Assume AuthService can refresh the CSRF token

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next.handle(req).pipe(
      catchError((error: HttpErrorResponse) => {
        // Check if it is a CSRF token mismatch error
        if (error.status === 403 && error.error && error.error.csrf === 'token_mismatch') {
          // Request to refresh the CSRF token
          return this.authService.refreshCsrfToken().pipe(
            switchMap((token) => {
              // Clone the original request and set the new token
              const authReq = req.clone({
                headers: req.headers.set('X-CSRF-TOKEN', token)
              });
              // Retrying the original request with the new CSRF token
              return next.handle(authReq);
            })
          );
        }
        // Pass the error if it's not related to CSRF token mismatch
        return throwError(error);
      })
    );
  }
}
This Angular service interceptor catches any HttpErrorResponse and checks if the error is due to CSRF token mismatch (status code 403 and a specific error structure). If so, it attempts to refresh the CSRF token using an AuthService (a service you should implement that handles token refresh logic). After acquiring a new token, it clones the original request and sets the new CSRF token as a header, then retries the original request. If the error is not due to a CSRF mismatch, it simply forwards the error.