Introducción
flowchart LR
COMP["Componente: http.get()"] --> CHAIN["Cadena de interceptores"]
CHAIN --> AUTH["authInterceptor: añade Bearer JWT"]
AUTH --> LOG["loggingInterceptor: registra petición"]
LOG --> ERR["errorInterceptor: gestión central de errores"]
ERR --> NET["Petición HTTP real al backend"]
NET -->|response| ERR
ERR -->|catchError| RETRY["Reintentos / refresh token"]
CHAIN --> CONFIG["provideHttpClient(withInterceptors([...]))"]
Los interceptores HTTP en Angular permiten interceptar y manipular peticiones y respuestas HTTP de forma centralizada, facilitando una gestión global de la autenticación, el manejo de errores, el logging, y más.
En Angular 21, los interceptores funcionales (HttpInterceptorFn) son el enfoque estándar y recomendado. Se configuran mediante provideHttpClient(withInterceptors([...])) en app.config.ts.
Aplicaciones prácticas
Los interceptores HTTP tienen una amplia gama de usos:
- Autenticación y autorización: Añadir tokens de autenticación a las cabeceras de las peticiones automáticamente.
- Manejo de errores: Interceptación centralizada de errores para implementar estrategias de manejo como reintentos automáticos o redirecciones.
- Logging y auditoría: Registro de peticiones y respuestas para fines de auditoría y debugging.
- Caching: Almacenamiento en caché de respuestas para mejorar el rendimiento.
Crear un interceptor funcional
Para crear un interceptor funcional, utilizamos el comando ng generate interceptor:
ng generate interceptor auth
Esto genera el archivo con el siguiente contenido:
import { HttpInterceptorFn } from '@angular/common/http';
export const authInterceptor: HttpInterceptorFn = (req, next) => {
return next(req);
};
Puntos clave del código generado:
HttpInterceptorFn: Tipo que representa una función interceptora. Recibe la petición y el manejadornext.req: La petición HTTP que está siendo interceptada, de tipoHttpRequest<any>.next: Función que pasa la petición al siguiente interceptor en la cadena o al transporte HTTP.- El interceptor retorna un
Observable<HttpEvent<any>>que Angular maneja internamente.
Ejemplo: Interceptor de autenticación JWT
El caso de uso más habitual es añadir el token JWT a cada petición HTTP:
import { HttpInterceptorFn } from '@angular/common/http';
export const authInterceptor: HttpInterceptorFn = (req, next) => {
const token = localStorage.getItem('access_token');
if (token) {
const authReq = req.clone({
headers: req.headers.set('Authorization', `Bearer ${token}`)
});
return next(authReq);
}
return next(req);
};
Activar el interceptor en app.config.ts
Los interceptores funcionales se registran con provideHttpClient(withInterceptors([...])):
import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { provideHttpClient, withInterceptors } from '@angular/common/http';
import { routes } from './app.routes';
import { authInterceptor } from './auth.interceptor';
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes),
provideHttpClient(withInterceptors([authInterceptor]))
]
};
Ejemplo: Interceptor de manejo de errores
Un interceptor funcional para manejar errores de forma centralizada:
import { HttpInterceptorFn, HttpErrorResponse } from '@angular/common/http';
import { inject } from '@angular/core';
import { Router } from '@angular/router';
import { catchError, throwError } from 'rxjs';
export const errorInterceptor: HttpInterceptorFn = (req, next) => {
const router = inject(Router);
return next(req).pipe(
catchError((error: HttpErrorResponse) => {
if (error.status === 401) {
localStorage.removeItem('access_token');
router.navigate(['/login']);
}
console.error(`Error HTTP ${error.status}: ${error.message}`);
return throwError(() => error);
})
);
};
Se puede combinar con el interceptor de autenticación:
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes),
provideHttpClient(withInterceptors([authInterceptor, errorInterceptor]))
]
};
Los interceptores se ejecutan en el orden en que se proporcionan en el array.
Interceptor de logging
Otro ejemplo práctico es un interceptor para registrar las peticiones y sus tiempos de respuesta:
import { HttpInterceptorFn } from '@angular/common/http';
import { tap } from 'rxjs';
export const loggingInterceptor: HttpInterceptorFn = (req, next) => {
const startTime = Date.now();
console.log(`[HTTP] ${req.method} ${req.url}`);
return next(req).pipe(
tap({
next: () => {
const elapsed = Date.now() - startTime;
console.log(`[HTTP] ${req.method} ${req.url} completado en ${elapsed}ms`);
},
error: (error) => {
const elapsed = Date.now() - startTime;
console.error(`[HTTP] ${req.method} ${req.url} falló en ${elapsed}ms`, error);
}
})
);
};
Enfoque legacy: Interceptores basados en clases
En versiones anteriores de Angular se utilizaban interceptores basados en clases que implementaban la interfaz HttpInterceptor. Este enfoque sigue funcionando en aplicaciones existentes pero no es el recomendado para nuevos proyectos.
// Enfoque legacy (no recomendado en Angular 21)
import { Injectable } from '@angular/core';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor(private authService: AuthService) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const authToken = this.authService.getToken();
const authReq = req.clone({
headers: req.headers.set('Authorization', `Bearer ${authToken}`)
});
return next.handle(authReq);
}
}
Para registrar un interceptor basado en clases se utilizaba HTTP_INTERCEPTORS en los providers:
// Registro legacy con NgModules (no recomendado)
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true }
]
El enfoque funcional con HttpInterceptorFn y provideHttpClient(withInterceptors([...])) es más conciso, tiene mejor tree-shaking y se integra naturalmente con el patrón standalone de Angular 21.
Consideraciones importantes
- Asegura que el servicio de autenticación proporcione el token de manera sincrónica.
- Maneja adecuadamente los escenarios de tokens expirados o inválidos, considerando redirecciones o la renovación automática del token.
- Utiliza HTTPS para proteger los tokens de autenticación durante su transmisión.
- Evita exponer información sensible en los mensajes de error.
- Los interceptores funcionales pueden usar
inject()para acceder a cualquier servicio registrado.
Alan Sastre
Ingeniero de Software y formador, CEO en CertiDevs
Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, Angular es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.
Más tutoriales de Angular
Explora más contenido relacionado con Angular y continúa aprendiendo con nuestros tutoriales gratuitos.
Aprendizajes de esta lección
- Comprender el flujo de trabajo de los interceptores HTTP en Angular.
- Implementar interceptores HTTP funcionales con HttpInterceptorFn.
- Autenticación y autorización con interceptores
- Manejo de errores con interceptores.