15-¿QUÉ ES JWT? - DIFERENCIAS entre SESIONES y TOKENS

  https://www.youtube.com/watch?v=k3pbXdwlodw&t=54s

Tutorial: ¿QUÉ ES JWT? - DIFERENCIAS entre SESIONES y TOKENS

Introducción

¡Hola! Muy buenas, bienvenidos a un nuevo tutorial en "Aprende Boulder". ¿Qué tal estáis? Yo estoy muy bien y espero que vosotros también. Yo soy Cézanne y esto es "Aprende", un canal dedicado a la programación, al desarrollo web y a todo lo que rodea el desarrollo web.

En este tutorial, vamos a tratar el tema de JWT (JSON Web Tokens). Veremos qué son estos tokens, cómo están formados, cómo se pueden crear y después explicaremos cómo funcionaría un token en un sistema de autenticación. Finalmente, terminaremos viendo las diferencias entre un sistema de autenticación con sesiones y otro con tokens, y analizaremos las ventajas y desventajas de cada sistema.

Si te interesa el tema, ¡no olvides darle like y suscribirte para más contenido como este! Vamos a ello.


¿Qué son los Tokens JWT?

JWT (JSON Web Tokens) es un estándar abierto basado en JSON que sirve para crear tokens de acceso. Estos tokens permiten transmitir información entre dos sistemas, como un cliente (navegador) y un servidor, a través de un objeto JSON. Además, están firmados digitalmente con una clave secreta, lo que permite su verificación en el servidor.


Estructura de un JWT

Para explicar la estructura de los JSON Web Tokens, podemos visitar la página oficial de JWT. Allí veremos que un token JWT tiene tres partes diferenciadas por colores y separadas por puntos:

  1. Header (Encabezado): Contiene información sobre el algoritmo usado (ej: HS256) y el tipo de token (generalmente "JWT").

  2. Payload (Carga útil): Aquí se guarda la información que lleva el token, como el ID de usuario, nombre, apellidos, etc.

  3. Signature (Firma): Esta firma verifica que el token no ha sido alterado y es válido. Se genera con una clave secreta (secret).

Importante:

  • Los tokens JWT son firmados, no encriptados. Esto significa que cualquiera puede decodificarlos y ver su contenido, pero no modificarlos sin la clave secreta.

  • Nunca almacenes datos confidenciales (como contraseñas) en el payload.


Autenticación con Sesiones vs. Tokens

Autenticación con Sesiones

El flujo de autenticación basado en sesiones es el siguiente:

  1. El usuario ingresa sus credenciales (username y password).

  2. El servidor verifica las credenciales y, si son correctas, crea una sesión (almacenada en memoria o base de datos).

  3. El servidor envía un session ID al cliente, que se guarda en las cookies del navegador.

  4. En cada petición posterior, el navegador envía el session ID al servidor.

  5. El servidor verifica el session ID y autentica al usuario.

  6. Cuando el usuario cierra sesión, la sesión se destruye tanto en el cliente como en el servidor.

Desventaja principal: Las sesiones son stateful (con estado), lo que significa que el servidor debe almacenarlas. Esto complica el escalamiento horizontal (añadir más servidores), ya que las sesiones deben compartirse entre todos los servidores.


Autenticación con Tokens

El flujo de autenticación basado en tokens es distinto:

  1. El usuario ingresa sus credenciales.

  2. El servidor verifica las credenciales y crea un token firmado.

  3. El token se envía al cliente y se guarda (generalmente en cookies o local storage).

  4. En cada petición posterior, el token se envía en el header (ej: Authorization: Bearer <token>).

  5. El servidor decodifica y valida el token.

  6. Cuando el usuario cierra sesión, el token se destruye solo en el cliente. No hay acción en el servidor.

Ventajas de los tokens:

  1. Stateless: No se almacenan en el servidor, lo que simplifica el escalamiento horizontal.

  2. Rendimiento: Los datos del usuario se guardan en el token, evitando llamadas adicionales a la base de datos.

  3. Compatibilidad: Funcionan mejor en aplicaciones móviles que las cookies.

Desventaja principal: Los tokens son difíciles de invalidar antes de su fecha de expiración. Para solucionarlo, a veces se almacenan en una base de datos para poder revocarlos, pero esto añade complejidad.


Conclusión

Tanto las sesiones como los tokens tienen sus pros y contras. Las sesiones son útiles en aplicaciones pequeñas o donde el estado del servidor no sea un problema, mientras que los tokens son ideales para aplicaciones escalables y multiplataforma.

¡Espero que este tutorial te haya sido útil! Si te ha gustado, no olvides darle like y suscribirte para más contenido. ¡Hasta la próxima!


Flujo completo y correcto:

1. Registro inicial (Crear cuenta)

text
POST /auth/register
Body: {
  "email": "usuario@ejemplo.com",
  "password": "mi_password_123",
  "name": "Juan Pérez"
}
  • El servidor guarda tu usuario y contraseña (encriptada) en la base de datos

  • Todavía no hay token

2. Login (Obtener token)

text
POST /auth/login  
Body: {
  "email": "usuario@ejemplo.com",
  "password": "mi_password_123"
}
  • ✅ Servidor verifica que las credenciales sean correctas

  • ✅ Genera el token con información como:

json
{
  "userId": "123",
  "email": "usuario@ejemplo.com",
  "iat": 1627837283,       // Fecha de creación
  "exp": 1627840883        // Fecha de expiración (ej: 1 hora)
}
  • ✅ Firma el token con una clave secreta que solo el servidor conoce

  • ✅ Envía el token al cliente

3. Peticiones con token

text
GET /api/mis-datos
Headers: {
  "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
  • 🔍 Servidor verifica:

    • ¿El token está bien formado?

    • ¿La firma es válida? (¿lo firmé yo?)

    • ¿No ha expirado?

    • ¿El usuario todavía existe?

4. Procesamiento

  • Si TODO ES VÁLIDO: Procesa tu petición y te responde

  • Si ALGO FALLA: Retorna error 401 Unauthorized o 403 Forbidden


Ejemplo de verificación en el servidor:

javascript
const jwt = require('jsonwebtoken');
const CLAVE_SECRETA = 'mi_clave_super_secreta';

// Middleware de verificación
function verificarToken(req, res, next) {
  const token = req.headers.authorization?.replace('Bearer ', '');
  
  if (!token) {
    return res.status(401).json({ error: 'Token requerido' });
  }

  try {
    // Verificar y decodificar el token
    const decoded = jwt.verify(token, CLAVE_SECRETA);
    
    // decoded = { userId: "123", email: "usuario@ejemplo.com", iat: 1627837283, exp: 1627840883 }
    
    req.usuario = decoded; // Agregar info del usuario a la request
    next(); // Continuar con la petición
    
  } catch (error) {
    return res.status(403).json({ error: 'Token inválido o expirado' });
  }
}

// Uso en una ruta protegida
app.get('/api/mis-datos', verificarToken, (req, res) => {
  // Solo llega aquí si el token es válido
  console.log('Usuario autenticado:', req.usuario.userId);
  // Procesar la petición...
});

¿Qué pasa si alguien modifica el token?

Si un cliente intenta modificar el token (ej: cambiar userId: 123 por userId: 456):

  1. La firma digital dejará de coincidir

  2. jwt.verify() fallará inmediatamente

  3. El servidor rechazará la petición


Resumen:

✅ Credenciales correctas → Servidor genera y firma token
✅ Cliente envía token en headers + datos en body
✅ Servidor verifica firma y validez
✅ Si todo ok → Procesa la petición
❌ Si algo falla → Rechaza la petición

¡Perfecto! Ahora sí tienes el concepto 100% claro. ¿Te queda alguna duda? 😊

Comentarios

Entradas más populares de este blog

1-Autenticación JWT en PHP: Explicación y Ejemplo

8-JWT en 10 minutos - ¿Qué es JWT? ¿Para que sirve? ¿Cuando usarlo? ¿Cómo se usa?

2-JSON Web Tokens