JWT vs Sesión: Qué Autenticación Elegir

Cierra la sesión de un usuario en una app basada en sesiones y el servidor lo olvida en la siguiente petición. Cierra la sesión en una app basada en JWT y, a menos que hayas montado un mecanismo extra, el token que tiene en la mano sigue siendo válido hasta que expira. Esa diferencia es la decisión real detrás de “JWT vs sesión”. El resto se deriva de ahí. Qué guarda realmente una sesión Una sesión mantiene el estado del usuario en el servidor y al navegador solo le pasa una clave de búsqueda. ...

16 de octubre de 2026 · 8 min · 1555 palabras · SpaghettiCoder

LocalStorage, SessionStorage y Cookies: Cuál Usar

Un endpoint de login te devuelve un JWT, y tienes tres lugares donde guardarlo: una cookie, localStorage o sessionStorage. Si eliges mal, un bug de XSS se lleva el token, o el token nunca llega a tu API. Las tres opciones guardan strings en el navegador. Se diferencian en quién puede leerlas, cuánto duran y si el servidor llega a verlas. En qué se diferencian localStorage, sessionStorage y las cookies localStorage y sessionStorage son la misma API, la interfaz Storage: setItem, getItem, removeItem, clear, claves string y valores string. La diferencia está en la duración. localStorage sobrevive a cerrar el navegador y reiniciar la máquina, y se queda hasta que algo lo borra. Safari es la excepción: con la prevención de rastreo activada, borra el almacenamiento escrito por script de un sitio con el que el usuario no ha interactuado en siete días. sessionStorage pertenece a una pestaña y muere cuando esa pestaña se cierra. Si escribes la misma URL en una segunda pestaña obtienes un sessionStorage nuevo y vacío; solo “Duplicar pestaña” lo copia. ...

5 de octubre de 2026 · 8 min · 1538 palabras · SpaghettiCoder

Qué Es CORS y Cómo Arreglar los Errores CORS

Tu frontend corre en http://localhost:5173, tu API en http://localhost:4000, y la llamada fetch que funcionaba sin problemas en Postman falla en el navegador con una pared de texto rojo: Access to fetch at 'http://localhost:4000/api/users' from origin 'http://localhost:5173' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Es muy probable que tu servidor haya procesado esa petición y devuelto un 200. El navegador se negó a entregar la respuesta a tu JavaScript. ...

26 de septiembre de 2026 · 8 min · 1674 palabras · SpaghettiCoder

Túneles SSH: Redirección de Puertos Local, Remota y Dinámica

¿Cómo llegar a una base de datos que solo escucha en localhost? Una instancia de Postgres en un servidor remoto está enlazada a 127.0.0.1 a propósito. Nada en la red puede alcanzarla, solo los procesos que corren en esa misma máquina. Tu portátil no es esa máquina, así que psql -h remote-server -p 5432 falla antes de llegar siquiera a la autenticación. Abrir el puerto al mundo anula la razón por la que se enlazó al loopback en primer lugar. ...

24 de septiembre de 2026 · 8 min · 1553 palabras · SpaghettiCoder

Qué Es TLS y Cómo Funciona el Cifrado HTTPS

Qué protege TLS realmente en una conexión HTTPS Carga una página por http:// sin cifrar en una red que no controlas, un aeropuerto o el router de una cafetería, y todo lo que envías viaja como texto legible. La ruta de la URL, las cookies, los campos del formulario, la contraseña en un POST de login: cualquiera en esa red con un sniffer de paquetes lo lee al vuelo. TLS, Transport Layer Security, es el protocolo que corta eso. Se sitúa entre TCP y el protocolo de aplicación, así que cuando HTTP empieza a hablar, la conexión ya está cifrada y ligada a una identidad de servidor verificada. HTTPS es HTTP corriendo sobre esa conexión en lugar de una en texto plano. ...

20 de septiembre de 2026 · 11 min · 2150 palabras · SpaghettiCoder

Variables de Entorno y Secrets en Docker

Dónde terminan las variables de entorno de un contenedor Arranca un contenedor con -e DB_PASSWORD=hunter2 y ejecuta docker inspect sobre él: 1 2 docker run -d --name api -e DB_PASSWORD=hunter2 nginx:alpine docker inspect --format '{{json .Config.Env}}' api 1 ["DB_PASSWORD=hunter2","PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"] La contraseña queda ahí en texto plano, legible por cualquiera con acceso al socket de Docker, por docker exec api env y por cualquier proceso que corra dentro del contenedor. No es un bug: es justo para lo que existen las variables de entorno. El problema es usarlas para valores que nunca deberían ser tan visibles. ...

9 de septiembre de 2026 · 7 min · 1280 palabras · SpaghettiCoder