Seguridad JWT en Angular

Avanzado
Angular
Angular
Actualizado: 04/05/2026

Introducción a JWT

sequenceDiagram
    participant User
    participant Angular
    participant API as Backend
    participant Storage as localStorage
    User->>Angular: Login con email/password
    Angular->>API: POST /auth/login
    API->>API: Verifica credenciales
    API->>API: Firma JWT con secret
    API-->>Angular: 200 + { token, refresh }
    Angular->>Storage: Guarda token + refresh
    User->>Angular: Navega a /private
    Angular->>Angular: AuthGuard lee Storage
    Angular->>Angular: Decodifica payload<br/>verifica exp
    alt Token válido
        Angular->>API: GET /api/data<br/>Authorization: Bearer JWT
        API->>API: Verifica firma
        API-->>Angular: 200 + data
    else Token expirado
        Angular->>API: POST /auth/refresh
        API-->>Angular: nuevo JWT
        Angular->>Storage: Actualiza token
    else Token inválido
        Angular->>Angular: Redirige /login
    end

Los JSON Web Tokens (JWT) en Angular son cruciales para desarrolladores que buscan implementar autenticación y autorización seguras en sus aplicaciones web. JWT ofrece una manera compacta y autónoma de transmitir información segura entre partes como un objeto JSON. Esta información puede ser verificada y confiada porque está firmada digitalmente. Angular, siendo uno de los frameworks más populares para el desarrollo de aplicaciones web, proporciona un ecosistema adecuado para integrar JWT en la gestión de sesiones de usuario.

Historia y origen de JWT

JSON Web Tokens (JWT) surgieron como una solución a la necesidad de un estándar de tokens de acceso que permitiera la comunicación entre diferentes sistemas de manera segura. Su especificación, definida en el RFC 7519, establece cómo los tokens pueden ser usados para intercambiar información entre dos partes de manera segura. Esta característica los ha hecho sumamente populares en la implementación de autenticación y autorización en aplicaciones web modernas, incluyendo aquellas desarrolladas con Angular.

Los JWT son importantes porque proporcionan un método estandarizado y ligero para la autenticación de usuarios y la autorización de solicitudes, sin necesidad de mantener un estado de sesión en el servidor. Esto es especialmente útil en arquitecturas de aplicaciones distribuidas y microservicios. Además, su capacidad para ser firmados digitalmente asegura que la información que contienen puede ser verificada y confiada sin necesidad de una consulta adicional al servidor de autenticación.

Diferenciación de JWT de otros métodos de autenticación

Los JSON Web Tokens (JWT) representan un avance significativo en la autenticación y autorización de aplicaciones web comparados con métodos tradicionales, como las sesiones basadas en cookies.

A diferencia de las cookies, que requieren almacenamiento del estado de la sesión en el servidor, los JWT son autónomos y contienen toda la información necesaria para verificar la identidad del usuario. Esta característica los hace ideales para aplicaciones escalables y distribuidas, donde mantener el estado de la sesión entre múltiples servidores puede ser problemático.

Además, los JWT pueden ser fácilmente transmitidos entre diferentes dominios y servicios, facilitando patrones de diseño como Single Sign-On (SSO) y comunicaciones entre microservicios, lo que contribuye a su popularidad y adopción generalizada en la industria.

Aplicaciones prácticas

  • Autenticación de usuario: En aplicaciones Angular, los JWT se usan comúnmente para autenticar usuarios. Después de que un usuario se autentica, el servidor genera un JWT que luego se devuelve al cliente y se almacena, típicamente en el almacenamiento local del navegador.
  • Autorización de solicitudes: Los JWT son enviados en los encabezados de las solicitudes HTTP para acceder a recursos protegidos en el servidor, permitiendo una fácil autorización de solicitudes basada en tokens.
  • Single Sign-On (SSO): Los JWT son una base para implementar SSO, permitiendo que los usuarios se autentiquen una vez y accedan a varios servicios sin necesidad de volver a autenticarse.

Implementación JWT en Angular 21

La autenticación con JWT implica dos partes principales: el proceso de inicio de sesión, donde el servidor valida las credenciales del usuario y genera un token; y el uso del token para futuras solicitudes que requieran autenticación. En Angular 21, este proceso se maneja mediante servicios con inject(), interceptores funcionales y guards funcionales.

Paso 1: Crear el servicio de autenticación auth.service.ts

El AuthService es el corazón de nuestro sistema de autenticación. Utiliza inject() para acceder a HttpClient:

import { Injectable, inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject } from 'rxjs';
import { tap } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class AuthService {
  private http = inject(HttpClient);
  private isLoggedIn = new BehaviorSubject<boolean>(this.hasToken());

  private hasToken(): boolean {
    return localStorage.getItem('access_token') !== null;
  }

  login(username: string, password: string) {
    return this.http.post<{token: string}>('https://yourapi.com/login', { username, password })
      .pipe(
        tap(response => {
          localStorage.setItem('access_token', response.token);
          this.isLoggedIn.next(true);
        })
      );
  }

  isAuthenticated() {
    return this.isLoggedIn.asObservable();
  }

  getToken(): string | null {
    return localStorage.getItem('access_token');
  }

  logout() {
    localStorage.removeItem('access_token');
    this.isLoggedIn.next(false);
  }
}

Paso 2: Crear componente de inicio de sesión

El componente de login con formulario reactivo:

import { Component, inject } from '@angular/core';
import { FormBuilder, ReactiveFormsModule } from '@angular/forms';
import { Router } from '@angular/router';
import { AuthService } from '../auth.service';

@Component({
  selector: 'app-login',
  imports: [ReactiveFormsModule],
  template: `
    <form [formGroup]="loginForm" (ngSubmit)="login()">
      <h1>Iniciar sesión</h1>
      <div>
        <input type="email" formControlName="email" placeholder="Email">
      </div>
      <div>
        <input type="password" formControlName="password" placeholder="Password">
      </div>
      <button type="submit">Iniciar sesión</button>
      @if (errorMessage) {
        <small class="text-danger">{{ errorMessage }}</small>
      }
    </form>
  `
})
export class LoginComponent {
  private authService = inject(AuthService);
  private router = inject(Router);
  private fb = inject(FormBuilder);

  loginForm = this.fb.group({
    email: [''],
    password: ['']
  });

  errorMessage = '';

  login() {
    const { email, password } = this.loginForm.value;
    this.authService.login(email!, password!).subscribe({
      next: () => this.router.navigate(['/home']),
      error: () => this.errorMessage = 'Credenciales incorrectas'
    });
  }
}

Paso 3: Crear el interceptor funcional auth.interceptor.ts

En Angular 21, los interceptores se definen como funciones HttpInterceptorFn:

import { HttpInterceptorFn } from '@angular/common/http';

export const authInterceptor: HttpInterceptorFn = (req, next) => {
  const token = localStorage.getItem('access_token');
  
  if (token) {
    const cloned = req.clone({
      headers: req.headers.set('Authorization', 'Bearer ' + token)
    });
    return next(cloned);
  }
  
  return next(req);
};

Paso 4: Registrar el interceptor en app.config.ts

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]))
  ]
};

Puntos clave:

  • provideHttpClient(withInterceptors([...])): Configura HttpClient globalmente con los interceptores funcionales.
  • Los componentes simplemente inyectan HttpClient con inject() sin necesidad de importar módulos adicionales.
  • El interceptor funcional se ejecuta automáticamente en cada petición HTTP.
Alan Sastre - Autor del tutorial

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 concepto y la estructura de JWT.
  • Integrar JWT en aplicaciones Angular con interceptores funcionales.
  • Autorización y protección de rutas con JWT y guards funcionales.
  • Uso de interceptores HTTP funcionales para añadir JWT a solicitudes.
  • Creación y validación de JWT en el servidor.