Angular

Angular

Tutorial Angular: Decodificar tokens JWT en Angular

Angular decodificar JWT: implementación. Aprende a decodificar JWT en Angular con ejemplos prácticos y detallados.

Introducción

Un token JWT (JSON Web Token) es un estándar abierto (RFC 7519) que define una forma compacta y autónoma de transmitir información de forma segura entre partes como un objeto JSON. Esta información puede ser verificada y de confianza porque está firmada digitalmente. 

En aplicaciones donde el frontend está desacoplado del backend es habitual utilizar seguridad basada en tokens JWT.

Creación de interfaces para recibir token JWT

Crear el archivo token.dto.ts para guardar las interfaces relativas a la gestión de tokens:

// Respuesta del backend con el token JWT tras hacer login exitoso
export interface Token {
  token: string;
}

// Token JWT decodificado para acceder a sus datos
export interface DecodedToken {
  sub: number;
  email: string;
  role: string;
  iat: number;
  exp: number;
}

Creación de servicio de autenticación

Creamos un servicio llamado AuthenticationService con el siguiente comando:

ng generate service authentication/authentication

Este servicio será el encargado de almacenar el estado de autenticación del usuario en la aplicación.

Guardar el token JWT

@Injectable({
  providedIn: 'root'
})
export class AuthenticationService {

  isLoggedIn = new BehaviorSubject<boolean>(this.hasToken());

  hasToken(): boolean {
    return localStorage.getItem("jwt_token") !== null;
  }
  
 // Este método se invoca tras hacer login en login.component.ts
  handleLogin(token: string) {
    // guardar el token en el almacenamiento del navegador
    localStorage.setItem("jwt_token", token);
    this.isLoggedIn.next(true);

  }
}

Saber si el usuario está autenticado

En la propia barra de navegación o navbar.component.ts es posible detectar si el usuario tiene un token (se ha autenticado con login).

En base al token mostramos un botón de Iniciar sesión o Cerrar sesión.

navbar.component.ts:

@Component({
  selector: 'app-navbar',
  standalone: true,
  imports: [RouterLink, RouterLinkActive, NgbDropdownModule],
  templateUrl: './navbar.component.html',
  styleUrl: './navbar.component.css'
})
export class NavbarComponent {

  isLoggedIn = false;
  
    constructor(
    private authService: AuthenticationService,
    private router: Router
    ) {
    // Esto permite que el componente Navbar se entere de que ha ocurrido un login exitoso
    this.authService.isLoggedIn.subscribe(isLoggedIn => this.isLoggedIn = isLoggedIn);

  }
}

En el archivo navbar.component.html se puede utilizar el boolean isLoggedIn con un if para determinar si mostrar botones de Mi cuenta y Logout o botones de Iniciar Sesión y Registro.

   @if(isLoggedIn) {
          <button type="button" class="btn btn-warning ms-2" (click)="logout()">
            Logout
            <i class="bi bi-box-arrow-right ms-2"></i>
          </button>
        } @else {
          <button type="button" class="btn btn-success ms-2" routerLink="/login">
            Login
            <i class="bi bi-box-arrow-in-right ms-2"></i>
          </button>
          <button type="button" class="btn btn-secondary ms-2" routerLink="/register">
            Registro
            <i class="bi bi-person-plus ms-2"></i>
          </button>
        }

Borrar el token JWT para hacer logout

authentication.service.ts se crea un método que elimina el token JWT del localStorage y cambia el boolean isLoggedIn a false.


@Injectable({
  providedIn: 'root'
})
export class AuthenticationService {

  isLoggedIn = new BehaviorSubject<boolean>(this.hasToken());

  handleLogin(token: string) {
    // .... código 

  }
  
  hasToken(): boolean {
    return localStorage.getItem("jwt_token") !== null;
  }
  
  // Este método se invoca desde el botón "Cerrar sesión" de la navbar
  logout() {
    localStorage.removeItem("jwt_token"); // Elimina el token
    this.isLoggedIn.next(false);

  }
}

Decodificar el token JWT

Primero instalamos la librería jwt-decode para poder decodificar el token y extraer la información que contiene como por ejemplo: id, email, rol del usuario.

npm install jwt-decode

Comprobar si la librería se ha agregado al proyecto revisando el archivo package.json:

Si estamos trabajando en un proyecto con más personas, las otras deberán ejecutar el comando:

 npm install 

Esto garantiza que todos los miembros del equipo descargan las librerías y pueden utilizarlas.

Usar el método jwtDecode() en el AuthenticationService para decodificar el token JWT:

  userEmail = new BehaviorSubject<string>(this.getCurrentEmail());

  // Método para extraer el email del token JWT
  getCurrentEmail() {
    // decodificar el token y extraer la información que tiene dentro
    const token = localStorage.getItem("jwt_token");
    if(!token) return '';

    const decodedToken = jwtDecode(token) as DecodedToken; // DecodedToken en token.dto.ts
    return decodedToken.email;
  }
  
  // Actualizar el método de login para que obtenga el email:
  handleLogin(token: string) {
    // guardar el token en el almacenamiento del navegador
    localStorage.setItem("jwt_token", token);
    this.isLoggedIn.next(true);
    this.userEmail.next(this.getCurrentEmail());

  }

Si guardamos el email en una variable BehaviourSubject entonces podemos utilizarlo en otros lugares de la plataforma, por ejemplo para mostrarlo en la navbar y que el usuario sepa cuál es su cuenta con su email.

Luego en la navbar.component.ts se puede suscribir a userEmail y mostrar el email si existe. Ejemplo:

    this.authService.userEmail.subscribe(userEmail => this.userEmail = userEmail);

Extraer el rol del token JWT

Actualizar el AuthenticationService para detectar si el usuario es administrador:

   isAdmin = new BehaviorSubject<boolean>(this.getIsAdmin());

   getIsAdmin() {
    const token = localStorage.getItem("jwt_token");
    if(!token) return false;

    const decodedToken = jwtDecode(token) as DecodedToken;
    return decodedToken.role === 'admin'; // true o false
  }

Luego esta variable isAdmin es posible suscribirse a ella desde la navbar o cualquier otro componente de la aplicación.

Código final AuthenticationService

Este es el resultado final del archivo authentication.service.ts:

@Injectable({
  providedIn: 'root'
})
export class AuthenticationService {

  // Comprueba si un usuario ya está logueado, es decir, existe token
  // Notifica a quien se haya suscrito a este booleano de que ha ocurrido un login
  isLoggedIn = new BehaviorSubject<boolean>(this.hasToken());
  userEmail = new BehaviorSubject<string>(this.getCurrentEmail());
  isAdmin = new BehaviorSubject<boolean>(this.getIsAdmin());

  hasToken(): boolean {
    return localStorage.getItem("jwt_token") !== null;
  }
  handleLogin(token: string) {
    // guardar el token en el almacenamiento del navegador
    localStorage.setItem("jwt_token", token);
    this.isLoggedIn.next(true);
    this.userEmail.next(this.getCurrentEmail());
    this.isAdmin.next(this.getIsAdmin());
  }
  getCurrentEmail() {
    // decodificar el token y extraer la información que tiene dentro
    const token = localStorage.getItem("jwt_token");
    if(!token) return '';

    const decodedToken = jwtDecode(token) as DecodedToken;
    return decodedToken.email;
  }
  getIsAdmin() {
    const token = localStorage.getItem("jwt_token");
    if(!token) return false;

    const decodedToken = jwtDecode(token) as DecodedToken;
    return decodedToken.role === 'admin'; // true o false
  }
  logout() {
    localStorage.removeItem("jwt_token");
    this.isLoggedIn.next(false);
    this.userEmail.next('');
    this.isAdmin.next(false);
  }

}
Certifícate en Angular con CertiDevs PLUS

Ejercicios de esta lección Decodificar tokens JWT en Angular

Evalúa tus conocimientos de esta lección Decodificar tokens JWT en Angular con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.

Signals en Angular

Angular
Puzzle

Guards funcionales

Angular
Test

Decodificar JWT en Angular

Angular
Test

Servicio con HttpClient

Angular
Código

Ciclo de vida de componentes en Angular

Angular
Test

Gestión de productos de Fake Store API

Angular
Proyecto

Data binding en Angular

Angular
Test

Routes sin módulos en Angular

Angular
Código

Router en Angular

Angular
Test

Instalación de Angular

Angular
Puzzle

Route Guards basados en interfaces

Angular
Código

La directiva @if en Angular

Angular
Puzzle

Formularios reactivos en Angular

Angular
Código

Servicios en Angular

Angular
Puzzle

Interceptor funcional

Angular
Test

Servicio con Array

Angular
Código

La directiva @for en Angular

Angular
Puzzle

Interceptores HTTP

Angular
Código

Componentes standalone true

Angular
Puzzle

Formularios con ngModel en Angular

Angular
Puzzle

Routes en Angular

Angular
Test

Comunicación entre componentes Angular

Angular
Test

Parámetros en rutas con ActivatedRoute

Angular
Test

CRUD de Restaurantes y Platos

Angular
Proyecto

Tablas en Angular Material

Angular
Puzzle

Formulario de registro de usuarios

Angular
Proyecto

Instalación y uso de NgBoostrap

Angular
Puzzle

Desarrollo de componentes Angular

Angular
Test

JWT en Angular

Angular
Código

Formularios reactivos en Angular

Angular
Puzzle

Formularios en Angular Material

Angular
Puzzle

Layout con Angular Material

Angular
Puzzle

Effects en Angular

Angular
Test

Data binding

Angular
Código

HttpClient en servicios de Angular

Angular
Puzzle

Desarrollo de módulos Angular

Angular
Puzzle

Comandos Angular CLI

Angular
Puzzle

Subir archivo en formularios

Angular
Test

La directiva routerLink en Angular

Angular
Test

Todas las lecciones de Angular

Accede a todas las lecciones de Angular y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.

Instalación Angular

Angular

Introducción Y Entorno

Comandos Angular Cli

Angular

Introducción Y Entorno

Desarrollo De Componentes Angular

Angular

Componentes

Data Binding En Angular

Angular

Componentes

Ciclo De Vida De Componentes En Angular

Angular

Componentes

Comunicación Entre Componentes Angular

Angular

Componentes

La Directiva @If En Angular

Angular

Componentes

La Directiva @For En Angular

Angular

Componentes

Componentes Standalone

Angular

Componentes

Desarrollo De Módulos Angular

Angular

Módulos

Routes En Angular

Angular

Enrutado Y Navegación

Router En Angular

Angular

Enrutado Y Navegación

La Directiva Routerlink En Angular

Angular

Enrutado Y Navegación

Parámetros En Rutas Con Activatedroute

Angular

Enrutado Y Navegación

Routes Sin Módulos En Angular

Angular

Enrutado Y Navegación

Servicios En Angular

Angular

Servicios E Inyección De Dependencias

Httpclient En Servicios De Angular

Angular

Servicios E Inyección De Dependencias

Formularios Con Ngmodel En Angular

Angular

Formularios

Formularios Reactivos En Angular

Angular

Formularios

Subir Archivo En Formularios

Angular

Formularios

Layout Con Angular Material

Angular

Integración Con Angular Material

Tablas En Angular Material

Angular

Integración Con Angular Material

Formularios En Angular Material

Angular

Integración Con Angular Material

Instalación Y Uso De Ngboostrap

Angular

Integración Con Bootstrap Css

Signals En Angular

Angular

Signals Y Reactividad

Effects En Angular

Angular

Signals Y Reactividad

Route Guards Basados En Interfaces

Angular

Autenticación Y Autorización

Guards Funcionales

Angular

Autenticación Y Autorización

Interceptores Http Basados En Interfaz

Angular

Autenticación Y Autorización

Interceptores Http Funcionales

Angular

Autenticación Y Autorización

Seguridad Jwt En Angular

Angular

Autenticación Y Autorización

Decodificar Tokens Jwt En Angular

Angular

Autenticación Y Autorización

Certificados de superación de Angular

Supera todos los ejercicios de programación del curso de Angular y obtén certificados de superación para mejorar tu currículum y tu empleabilidad.

En esta lección

Objetivos de aprendizaje de esta lección

  • Obtener token JWT
  • Decodificar token JWT
  • Notificar a navbar de que el usuario se ha autenticado
  • Notificar a navbar de cuál es el email del usuario
  • Login y Logout