Logo

dev-resources.site

for different kinds of informations.

JSON Web Tokens (JWT): Guía Esencial y Buenas Prácticas

Published at
1/7/2025
Categories
jwt
authentication
cybersecurity
spanish
Author
codewebnow
Author
10 person written this
codewebnow
open
JSON Web Tokens (JWT): Guía Esencial y Buenas Prácticas

En aplicaciones modernas, como aquellas que usan APIs RESTful, la seguridad es una prioridad. Uno de los métodos más efectivos y populares para manejar autenticación y autorización es mediante JSON Web Tokens (JWT). Este artículo es una guía completa para desarrolladores que buscan implementar JWT en sus aplicaciones de manera eficiente y segura.

¿Qué es un JWT y por qué usarlo?

Un JSON Web Token es un estándar abierto (RFC 7519) que se utiliza para transmitir información entre dos partes de forma segura como un objeto JSON. Un JWT tiene tres componentes principales:

  1. Header: Describe el tipo de token y el algoritmo usado para la firma (por ejemplo, HS256).
  2. Payload: Contiene los datos que queremos transmitir, como el ID de usuario o permisos.
  3. Signature: Asegura que el token no ha sido modificado desde que fue emitido.

Estructura de un JWT

A diferencia de otros métodos de autenticación, los JWT son:

  • Sin estado: No es necesario guardar tokens en el servidor, lo que reduce la carga de almacenamiento.
  • Seguro: Usan algoritmos de firma (como HMAC o RSA) para garantizar la integridad del token.
  • Flexible: Compatible con sistemas distribuidos y microservicios.

¿Cuándo deberías usar JWT?

Los JWT son ideales para aplicaciones que requieren autenticación en APIs RESTful. Algunos casos de uso comunes incluyen:

  • Autenticación de usuarios en aplicaciones web o móviles.
  • Manejo de sesiones sin estado en arquitecturas de microservicios.
  • Compartir datos entre servicios confiables.

Diferencias entre JWT y Sesiones

Mientras que las cookies y las sesiones son métodos tradicionales de autenticación, los JWT son más adecuados para aplicaciones modernas. En la siguiente tabla os mostramos sus diferencias.

Característica JWT Sesiones
Modelo de almacenamiento Token se almacena en el cliente (localStorage, sessionStorage o cookies) Sesiones almacenan un identificador en cookies, con datos en el servidor.
Autenticación Stateless (sin estado): el servidor no guarda información del usuario. Stateful (con estado): el servidor guarda datos en memoria o base de datos.
Escalabilidad Ideal para aplicaciones distribuidas y microservicios, ya que no depende del estado del servidor. Menos escalable, ya que requiere sincronización de estado en el servidor.
Seguridad Firma digital (HS256, RS256) asegura la integridad, pero puede ser comprometido si se expone la clave secreta. Más seguro en servidores centralizados, ya que los datos sensibles no están en el cliente.
Revocación Difícil, requiere listas negras o acortar el tiempo de vida del token. Fácil, basta con eliminar el estado del usuario en el servidor.
Transporte Puede enviarse como header (Authorization: Bearer) o almacenarse en cookies. Utiliza cookies HTTP para transporte automático.

*Ejemplo práctico*: Cómo implementar JWT en Node.js

A continuación, os dejamos un ejemplo de sistema muy básico de autenticación JWT en JavaScript, en concreto en un proyecto con Express.js. Si sigues esta guía, tendrás una API protegida con rutas autenticadas en pocos minutos.

Paso 1: Configuración del proyecto

Primero, necesitas configurar un proyecto Node.js básico. Este paso incluye inicializar el proyecto, instalar las dependencias necesarias y configurar el entorno. Como gestor de paquetes usaremos npm e instalaremos las siguientes librerías.

mkdir jwt-auth && cd jwt-auth
npm init -y
npm install express jsonwebtoken body-parser dotenv
Enter fullscreen mode Exit fullscreen mode

Crearemos un archivo .env y ahí guardaremos la clave secreta que usaremos para firmar y desencriptar los tokens.

// .env
SECRET_KEY=mi_clave_super_segura
Enter fullscreen mode Exit fullscreen mode

Paso 2: Crear el servidor con Express

El siguiente paso es configurar un servidor Express. Aquí definimos las rutas y conectamos los middlewares necesarios, como el análisis de datos JSON.

// server.js

require('dotenv').config();
const express = require('express');
const bodyParser = require('body-parser');

// Importa las rutas y middlewares
const authRoutes = require('./routes/auth');
const protectMiddleware = require('./middlewares/protected');

const app = express();
app.use(bodyParser.json());

// Rutas públicas
app.use('/auth', authRoutes);

// Ruta protegida como ejemplo
app.get('/protected-route', protectMiddleware, (req, res) => {
  res.json({ message: `Bienvenido, usuario ${req.user.username}` });
});

app.listen(3000, () => console.log('Servidor corriendo en http://localhost:3000'));
Enter fullscreen mode Exit fullscreen mode

Paso 3: Generar JWT en el proceso de login

El login es el punto de entrada para autenticar usuarios. Cuando un usuario se autentica correctamente, el servidor genera un token JWT que el cliente puede usar para acceder a recursos protegidos.

Para simplificar, no hacemos uso de una base de datos y usamos el objeto USER. En un caso real, aquí tendríamos que acceder a nuestra base de datos.

// routes/auth.js

const express = require('express');
const jwt = require('jsonwebtoken');
const router = express.Router();

// Datos ficticios de usuario
const USER = { username: 'developer1', password: '12345', id: 1 };

router.post('/login', (req, res) => {
  const { username, password } = req.body;

  if (username !== USER.username || password !== USER.password) {
    return res.status(401).json({ message: 'Credenciales inválidas' });
  }

  const token = jwt.sign(
    { userId: USER.id, username: USER.username },
    process.env.SECRET_KEY,
    { expiresIn: '1h' }
  );

  res.json({ token });
});

module.exports = router;
Enter fullscreen mode Exit fullscreen mode

Paso 4: Proteger rutas con middleware

Para asegurarnos de que solo los usuarios autenticados puedan acceder a ciertas rutas, creamos un middleware que verifica la validez del token enviado en los encabezados HTTP.

// middlewares/protected.js

const jwt = require('jsonwebtoken');

module.exports = (req, res, next) => {
  const token = req.headers['authorization'];
  if (!token) {
    return res.status(403).json({ message: 'Token no proporcionado' });
  }

  try {
    const decoded = jwt.verify(token.split(' ')[1], process.env.SECRET_KEY);
    req.user = decoded;
    next();
  } catch (error) {
    return res.status(401).json({ message: 'Token inválido o expirado' });
  }
};
Enter fullscreen mode Exit fullscreen mode

Este middleware es el que hemos aplicado en la ruta /protected-route en el server.js. Por lo tanto, antes de ejecutarse el código que hay en la ruta, primero debe validarse todo lo que está en el middleware.

Paso 5: Probar la autenticación

En primer lugar, tenemos que iniciar el servidor Express.

node server.js
Enter fullscreen mode Exit fullscreen mode

A continuación, seguiremos el siguiente esquema cliente-servidor para probar la autenticación con JWT.

Esquema cliente-servidor de JWT

Con una herramienta como Postman o Thunder Client puedes probar el flujo de autenticación. Primero, solicita un token mediante un POST con los datos de autenticación {"username": "developer1", "password": "12345"} a la ruta de login /auth/login.

Login y obtención de un jwt

El token que nos devuelve es el que nos va a permitir acceder a las rutas protegidas por el middleware. Accederemos con un GET a /protected-route usando el esquema de autenticación Bearer.

Usando Thunder Client ya hay un espacio para ello, pero no deja de ser una cabecera HTTP del tipo:

Authorization: Bearer <TOKEN>
Enter fullscreen mode Exit fullscreen mode

Uso del token para acceder a rutas protegidas

También, podemos probar el caso en el que el token fuera inválido.

Caso de token inválido

Paso 6: Buenas prácticas con JWT

  1. Evita exponer claves secretas: Usa variables de entorno y nunca las incluyas en tu código fuente.
  2. Haz que los tokens sean de corta duración: Usa tiempos de expiración (expiresIn) razonables.
  3. Implementa Refresh Tokens: Para tokens de larga duración, usa un sistema de refresh tokens que permita emitir nuevos JWT sin requerir un nuevo login.
  4. Usa HTTPS: Protege los datos en tránsito cifrando las conexiones.

Si quieres saber más acerca de los JSON Web Tokens aquí tienes su documentación oficial.

Post originalmente publicado en https://codewebnow.com/blog/jwt/.

authentication Article's
30 articles in total
Favicon
Pushed Authorization Requests in .NET 9: Why and How to Use Them
Favicon
Google Authentication in MERN Stack
Favicon
JWT Authentication With NodeJS
Favicon
The Speakeasy Door to Your Network - Port Knocking (2)
Favicon
The Speakeasy Door to Your Network - Port Knocking (1)
Favicon
[Part 1] Rails 8 Authentication but with JWT
Favicon
Understanding Passkeys: The Behind-the-Scenes Magic of Passwordless Authentication
Favicon
Introduction to 3D Secure: Enhancing Online Payment Security
Favicon
Accessing the AuthAction Management API with Machine-to-Machine Application
Favicon
Ensuring Successful Passkey Deployment: Testing Strategies for Enterprises
Favicon
Learn Django REST Framework Authentication: A Complete Step-by-Step Python Guide
Favicon
Bulletproof JWT Authentication: Essential Security Patterns for Production Apps
Favicon
Django Authentication Made Easy: A Complete Guide to Registration, Login, and User Management
Favicon
How to Configure GitHub Authentication Using SSH Certificates
Favicon
Building an Attendance System Powered by Face Recognition Using React and FACEIO
Favicon
Password Composition Policies Are Bad and Here's Why
Favicon
JSON Web Tokens (JWT): Guía Esencial y Buenas Prácticas
Favicon
How to integrate Passkeys into Enterprise Stacks?
Favicon
Authentication and Authorization: A Tale of Security, Flaws, and Fixes 🏴‍☠️
Favicon
Using Clerk SSO to access Google Calendar and other service data
Favicon
Implementing FIDO2 Authentication: A Developer's Step-by-Step Guide
Favicon
How to Create a quick Authentication library for NestJS/MongoDB application
Favicon
Initial Planning & Technical Assessment for Passkeys
Favicon
Authentication with Clerk in NestJS Server Application
Favicon
SSO with Firebase Authentication
Favicon
Laravel Authentication Using Passport
Favicon
Django built-in authentication system
Favicon
Convex & Kinde
Favicon
Streamline enterprise customer onboarding with SAML and Clerk
Favicon
É seguro guardar dados do usuário no localStorage?

Featured ones: