Skip to main content

HTTP Interceptor

Package: @nauth-toolkit/client-angular

HTTP interceptor that handles authentication headers, CSRF tokens, and automatic token refresh.

Setup

// app.config.ts
import { provideHttpClient, withInterceptors } from '@angular/common/http';
import { authInterceptor } from '@nauth-toolkit/client-angular';

export const appConfig: ApplicationConfig = {
providers: [
provideHttpClient(withInterceptors([authInterceptor])),
],
};

Behavior

By Token Delivery Mode

ModeHeadersCredentialsCSRF
cookiesNonewithCredentials: trueAuto-attached
jsonAuthorization: Bearer <token>falseNot needed

CSRF Token Handling

For cookies mode, the interceptor automatically:

  1. Reads the CSRF token from cookie (default: nauth_csrf_token)
  2. Attaches it to mutating requests (POST, PUT, PATCH, DELETE)
  3. Uses configured header name (default: x-csrf-token)
// Configure CSRF in client config
{
provide: NAUTH_CLIENT_CONFIG,
useValue: {
baseUrl: 'https://api.example.com/auth',
tokenDelivery: 'cookies',
csrf: {
cookieName: 'nauth_csrf_token', // Default
headerName: 'x-csrf-token', // Default
},
onSessionExpired: () => {},
},
}

Automatic Token Refresh

On 401 response:

  1. Interceptor queues the failed request
  2. Calls refreshTokens() on the client
  3. Retries the original request with new tokens
  4. If refresh fails, calls onSessionExpired callback
Request → 401 → Refresh Tokens → Retry Request → Response
↓ (fail)
onSessionExpired()

Concurrency Handling

Multiple simultaneous 401s trigger only ONE refresh:

Request A → 401 ─┐
Request B → 401 ──┼→ Single Refresh → Retry All
Request C → 401 ─┘

Exports

ExportTypeDescription
authInterceptorHttpInterceptorFnFunctional interceptor (Angular 17+)
AuthInterceptorClassclassClass-based interceptor (NgModule)

Customization

Exclude Routes from Interception

The interceptor only adds auth to requests matching your baseUrl. External APIs are not affected.

For additional control, create a wrapper interceptor:

export const customAuthInterceptor: HttpInterceptorFn = (req, next) => {
// Skip auth for specific paths
if (req.url.includes('/public/')) {
return next(req);
}
return authInterceptor(req, next);
};

Custom Error Handling

Handle 401s differently:

export const customAuthInterceptor: HttpInterceptorFn = (req, next) => {
return authInterceptor(req, next).pipe(
catchError((error) => {
if (error.status === 401) {
// Custom handling
console.log('Authentication required');
}
return throwError(() => error);
}),
);
};