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:
Header (Encabezado): Contiene información sobre el algoritmo usado (ej: HS256) y el tipo de token (generalmente "JWT").
Payload (Carga útil): Aquí se guarda la información que lleva el token, como el ID de usuario, nombre, apellidos, etc.
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:
El usuario ingresa sus credenciales (username y password).
El servidor verifica las credenciales y, si son correctas, crea una sesión (almacenada en memoria o base de datos).
El servidor envía un session ID al cliente, que se guarda en las cookies del navegador.
En cada petición posterior, el navegador envía el session ID al servidor.
El servidor verifica el session ID y autentica al usuario.
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:
El usuario ingresa sus credenciales.
El servidor verifica las credenciales y crea un token firmado.
El token se envía al cliente y se guarda (generalmente en cookies o local storage).
En cada petición posterior, el token se envía en el header (ej:
Authorization: Bearer <token>).El servidor decodifica y valida el token.
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:
Stateless: No se almacenan en el servidor, lo que simplifica el escalamiento horizontal.
Rendimiento: Los datos del usuario se guardan en el token, evitando llamadas adicionales a la base de datos.
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)
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)
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:
{
"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
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 Unauthorizedo403 Forbidden
Ejemplo de verificación en el servidor:
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):
La firma digital dejará de coincidir
jwt.verify()fallará inmediatamenteEl 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
Publicar un comentario