Seguramente te ha pasado: el script funciona, inicia sesión en el sitio, agrega un producto al carrito, y de repente cambia la IP y el servidor responde como si fueras un visitante nuevo. La sesión se cierra, el carrito queda vacío, el token no es válido. ¿Molesto? Muchísimo. Pero este problema tiene una solución técnica clara, y en esta guía la vamos a resolver de principio a fin.

Introducción: por qué al cambiar de IP se cierra la sesión y se vacía el carrito

Seamos honestos: cuando la sesión se cae después de una rotación de IP, lo primero que uno quiere es culpar al cambio de dirección. «Cambió la IP, el servidor lo vio y lo reinició todo». A veces es cierto. Pero mucho más a menudo el problema no es la IP en sí, sino cómo está construido tu código: mezcla el estado de distintas sesiones, pierde cookies, envía tokens antiguos desde una nueva dirección. Vamos a aprender a evitar que esto suceda.

Qué obtendrá el lector al final

Al final de esta guía sabrás hacer lo siguiente. Primero, entender qué está realmente vinculado a la IP en el servidor y qué es un mito. Segundo, establecer una regla estricta de correspondencia: una sesión lógica equivale a un conjunto de cookies, equivale a una IP. Tercero, escribir código funcional en Python y Node.js que aísle el estado entre diferentes proxies y no mezcle datos. Cuarto, guardar el estado entre ejecuciones del programa y saber cuándo es más fácil descartarlo.

Para quién es esta guía

La guía está pensada para un nivel intermedio. Ya escribes código en Python o JavaScript, sabes qué es una petición HTTP y entiendes para qué sirven los proxies. No vamos a discutir qué tipo de rotación elegir: para eso hay materiales aparte. Aquí partimos de que la rotación de IP ya ocurre según tus reglas, y resolvemos una sola tarea: cómo no perder el estado durante esa rotación.

Qué necesitas saber de antemano

Es útil entender lo básico. Una cookie es un pequeño fragmento de datos que el servidor le pide al navegador o al cliente que recuerde y envíe de vuelta con cada solicitud. Una sesión es la forma que tiene el servidor de reconocerte entre peticiones. Un token es una cadena que confirma tu identidad o tu derecho a realizar una acción. Si estos términos todavía te resultan difusos, no te preocupes: en la sección de conceptos básicos los explicaremos en lenguaje sencillo.

Cuánto tiempo necesitarás

Leer y comprender la teoría te llevará unos cuarenta minutos. Analizar y ejecutar el código en tu lenguaje tomará otra hora u hora y media. La asimilación completa con experimentos en problemas reales tomará de dos a tres horas. No tengas prisa. Es mejor entender el principio lentamente que copiar rápido un código que luego se rompa de forma extraña.

Preparación previa: herramientas y entorno

Antes de escribir código, vamos a poner en orden el entorno de trabajo. Tomará un poco de tiempo, pero te ahorrará horas de depuración después.

Herramientas necesarias

  • Python 3.10 o superior: si trabajas con Python. En 2026 las versiones vigentes son 3.12 y 3.13, pero todo lo descrito funciona desde 3.10.
  • Node.js 20 LTS o superior: si trabajas con JavaScript. La versión 22 LTS también sirve.
  • Proxy con rotación de IP: ya deberías tener acceso a un pool de direcciones. El formato de conexión suele ser: protocolo, host, puerto, usuario y contraseña.
  • Editor de código: cualquiera sirve, por ejemplo un editor gratuito con resaltado de sintaxis.
  • Terminal o línea de comandos: para instalar librerías y ejecutar scripts.

Requisitos del sistema

Los requisitos son modestos. Cualquier computadora moderna puede manejarlo. Con cuatro gigabytes de RAM basta, pero si planeas muchas sesiones paralelas, mejor ocho o más. Más importante es una conexión a internet estable, porque si se pierde la conexión, las cookies podrían no guardarse correctamente.

Qué hay que instalar

Para Python instala dos librerías. Abre la terminal y ejecuta el comando para instalar el paquete requests y el paquete para trabajar con proxies. Se escribe así: primero el comando de instalación del gestor de paquetes y luego el nombre requests. Para serializar el estado te servirá el módulo estándar; no hace falta instalarlo por separado.

Para Node.js instala tres paquetes: axios para las peticiones, tough-cookie para gestionar el almacén de cookies y https-proxy-agent para conectarte a través de un proxy. Los tres se instalan con un solo comando de instalación de paquetes en tu proyecto.

Consejo: crea una carpeta virtual separada para el proyecto. En Python es un entorno virtual; en Node.js, un directorio aparte con un archivo de descripción de dependencias. Así no mezclarás librerías de distintos proyectos y evitarás conflictos de versiones.

Crear copias de seguridad

Si ya guardas cookies en archivos o en una base de datos, haz una copia antes de los experimentos. Vamos a cambiar la lógica de serialización y existe el riesgo de dañar los datos existentes. Simplemente copia la carpeta con los estados guardados a un lugar marcado como backup.

Verificación: después de instalar, asegúrate de que todo funciona. Ejecuta una comprobación rápida de la versión de Python o Node.js en la terminal. Deberías ver el número de versión sin errores. Luego intenta importar las librerías instaladas en modo interactivo; si la importación pasa sin problemas, todo está listo.

Conceptos básicos: qué está vinculado a la IP y qué es un mito

Esta es la sección teórica más importante. Hasta que no entiendas qué está realmente relacionado con la IP, estarás tratando la enfermedad equivocada. Vamos a repasar los tipos de datos uno por uno.

Sesión basada en cookies

Una sesión basada en cookies es cuando el servidor te entrega un identificador de sesión en forma de cookie y guarda el estado en su lado. Por ejemplo, una cookie llamada sessionid con una larga cadena aleatoria dentro. El servidor usa esa cadena para encontrar tu registro en su memoria. ¿Este mecanismo está vinculado a la IP? Por sí solo, no. La cookie funciona independientemente de la dirección. Pero muchos servicios añaden una verificación adicional: recuerdan desde qué IP se creó la sesión y, si llega una petición con la misma cookie desde otra dirección, la consideran sospechosa. Ahí es donde ocurre el cierre de sesión.

Token CSRF

El token CSRF es una protección contra la falsificación de solicitudes. El servidor emite un token y tú debes devolverlo al enviar un formulario o realizar una acción importante. Casi nunca está vinculado a la IP. Está ligado a la sesión, no a la dirección. El problema surge por otra razón: si pierdes la cookie de sesión, el token CSRF también se vuelve inválido, porque el servidor no puede asociarlo con tu sesión. Es decir, el problema aquí es secundario: una consecuencia de perder las cookies.

JWT

Un JWT es un token que lleva información dentro de sí y está firmado por el servidor. El cliente lo guarda y lo envía en el encabezado con cada solicitud. Un JWT clásico no está vinculado a la IP en absoluto. Es autosuficiente: el servidor verifica la firma y la fecha de expiración, y la dirección no le importa. Pero hay implementaciones donde el servidor adicionalmente guarda la vinculación del token a la IP en su lado o coloca la dirección dentro del token. En esos casos, el cambio de IP rompe la verificación. Eso no es una propiedad del JWT, sino una decisión de un servicio específico.

Sesión del servidor

La sesión del servidor es el nombre general para el estado que el servidor guarda en su lado y asocia con tu identificador. El carrito, el historial de visitas, el estado de autorización: todo eso suele vivir en la sesión del servidor. La vinculación a la IP aquí depende de la configuración del servicio. Algunos, por seguridad, vinculan la sesión rígidamente a la primera IP. Otros toleran el cambio de dirección. Por lo general, no lo sabes de antemano, así que construyes el código como si la vinculación existiera: es una estrategia segura.

El carrito

El carrito es un caso particular de la sesión del servidor o de una cookie. En tiendas simples, el carrito se guarda en una cookie directamente en el cliente. En las complejas, en el servidor, vinculado a la sesión. Si el carrito se vacía después de cambiar de IP, significa que estaba vinculado a una sesión del servidor que verifica la dirección. La solución es la misma: no cambiar la IP dentro de una misma sesión lógica, o guardar cuidadosamente todo el conjunto de cookies.

Resumen: dónde participa realmente la IP

Armemos el panorama. El mecanismo HTTP de cookies, CSRF y JWT no está vinculado a la IP. La vinculación aparece como una verificación adicional del lado del servicio, y no puedes controlarla. Lo único que controlas es la correspondencia entre la sesión, el conjunto de cookies y la IP en tu lado. De aquí surge la regla principal de esta guía.

Verificación: comprueba tu comprensión. Si después de cambiar de IP la sesión se cae, pero al volver a la IP anterior todo se restaura, entonces el servidor verifica la dirección de forma estricta. Si no se restaura ni con la IP anterior, simplemente perdiste las cookies en el código. Son dos diagnósticos distintos con tratamientos distintos.

Paso 1: Formulamos la regla de correspondencia

Objetivo de la etapa: fijar el principio principal y entender cómo expresarlo en la estructura del código.

La regla suena simple: una sesión lógica equivale a un conjunto de cookies, que equivale a una IP. Veamos qué significa en la práctica.

  1. Una sesión lógica es una cadena de solicitudes que representan un trabajo continuo: entraste, iniciaste sesión, hiciste algo, saliste. Todo eso es una sesión lógica.
  2. Un conjunto de cookies es un almacén de cookies separado que pertenece solo a esa sesión lógica y a nadie más.
  3. Una IP: durante una sesión lógica, la dirección no cambia. Si la rotación ocurre de todos modos, la sesión lógica se considera finalizada.

¿Cómo expresarlo en código? De forma muy clara: creamos un objeto contenedor que contiene tanto el almacén de cookies como la configuración del proxy. Mientras ese objeto viva, vive la sesión lógica. Cuando llegue el momento de cambiar de IP, o creamos un contenedor nuevo o, si el servicio tolera el cambio de dirección, transferimos cuidadosamente las cookies a un contenedor nuevo con la nueva IP.

⚠️ Atención: el error arquitectónico más común es guardar un conjunto único de cookies y asignarle diferentes proxies. Eso lo rompe todo con seguridad. Las distintas sesiones lógicas empiezan a pisarse las cookies entre sí y el servidor recibe datos contradictorios. Nunca hagas eso.

Consejo: piensa en la sesión lógica como en una persona. Una persona tiene un solo documento (las cookies) y una sola casa (la IP). Dos personas no pueden usar el mismo documento, y una persona no puede vivir en dos casas al mismo tiempo. Esta analogía te evitará la mayoría de los errores.

Verificación: dibuja en papel tu futura estructura. Deberías obtener varios bloques independientes, cada uno con su almacén de cookies y su propio proxy. No hay datos compartidos entre bloques. Si es así, entendiste la regla.

Paso 2: Práctica en Python: una Session por cada proxy

Objetivo de la etapa: escribir código funcional donde cada sesión lógica tenga su propio objeto requests.Session, su propio CookieJar y su propio proxy, aislados entre sí.

En la librería requests existe el objeto Session. Por sí mismo es un contenedor: guarda el almacén de cookies y puede aplicar configuraciones a todas las solicitudes. Es la base ideal para nuestra sesión lógica.

Estructura básica

  1. Crea una función que reciba los datos de un proxy y devuelva un objeto Session listo.
  2. Dentro de la función, crea un nuevo objeto Session.
  3. Asigna al objeto la configuración proxies: un diccionario con la dirección del proxy para los protocolos http y https.
  4. Devuelve el objeto. Ahora tienes un contenedor aislado.

El código se ve así. En una línea: importamos requests. Definimos la función make_session, que recibe una cadena proxy_url. Dentro escribimos s = requests.Session(). Luego s.proxies = diccionario, donde la clave http apunta a proxy_url y la clave https apunta a proxy_url. Al final, return s. Listo, la función está lista.

Por qué esto aísla el estado

Cada llamada a make_session crea un objeto completamente nuevo. El objeto nuevo tiene su propio almacén interno de cookies, llamado cookiejar. Las cookies que recibe una sesión no pueden pasar físicamente a otra, porque son objetos distintos en memoria. Eso es exactamente lo que buscábamos.

Uso de la sesión

  1. Obtén el objeto de sesión llamando a la función con el proxy deseado.
  2. Haz las solicitudes a través de los métodos del objeto: s.get o s.post.
  3. Las cookies que el servidor envíe en el encabezado Set-Cookie se guardarán automáticamente dentro del objeto.
  4. En las siguientes solicitudes a través del mismo objeto, esas cookies se enviarán de vuelta automáticamente.

Consejo: no crees una nueva Session para cada solicitud individual dentro de una misma sesión lógica. Entonces las cookies no se acumularán. Crea el objeto una sola vez para toda la sesión lógica y úsalo para todas las solicitudes de esa sesión.

Aislamiento entre hilos

Si trabajas con varios hilos, cada hilo debe tener su propio objeto Session. El objeto Session no es seguro para hilos. Esto significa que si dos hilos escriben cookies en el mismo objeto al mismo tiempo, los datos pueden dañarse.

  1. Usa el mecanismo de datos locales del hilo. En Python es el objeto threading.local.
  2. Al iniciar cada hilo, crea una sesión separada para él y guárdala en el almacenamiento local del hilo.
  3. Dentro del hilo, accede solo a tu propia sesión, sin tocar las de los demás.

En la práctica se ve así: creamos un objeto global local = threading.local(). Al comenzar el trabajo del hilo, comprobamos si local tiene un atributo session. Si no lo tiene, lo creamos llamando a make_session con el proxy asignado a ese hilo. Luego, en el hilo, usamos local.session para todas las solicitudes.

⚠️ Atención: nunca pases un objeto Session entre hilos como recurso compartido. Aunque parezca que las solicitudes van una tras otra, el planificador puede cambiar de hilo en el peor momento y obtendrás cookies mezcladas. A cada hilo, su propio objeto.

Rotación dentro de la lógica

Cuando se produce la rotación de IP y necesitas una dirección nueva, haz lo siguiente. Finaliza la sesión lógica actual: si el servidor está vinculado rígidamente a la IP, simplemente crea un nuevo objeto Session con el nuevo proxy y empieza desde cero: vuelve a iniciar sesión. Si el servidor tolera el cambio de dirección, puedes transferir las cookies, como veremos en el paso sobre el almacenamiento del estado.

Verificación: ejecuta dos sesiones con proxies diferentes, inicia sesión en cada una en un servicio de prueba que muestre tu IP y tus cookies. Asegúrate de que cada sesión vea su propia IP y su propio conjunto de cookies. Si los datos no se mezclan, el aislamiento funciona correctamente.

Paso 3: Lo mismo en Node.js

Objetivo de la etapa: armar una construcción equivalente en JavaScript usando axios, tough-cookie y un agente de proxy.

En el ecosistema de Node.js no hay un objeto listo del nivel de Session, así que lo armaremos a partir de tres partes. El almacén de cookies lo tomaremos de tough-cookie. La conexión a través del proxy la proporcionará un agente. Las solicitudes las hará axios.

Armamos el contenedor

  1. Importa la clase CookieJar de la librería tough-cookie.
  2. Importa la función para crear un agente proxy de la librería https-proxy-agent.
  3. Importa axios.
  4. Crea una función makeClient que reciba la dirección del proxy y devuelva un objeto configurado.

Dentro de la función, crea una nueva instancia del almacén: const jar = new CookieJar(). Crea el agente proxy pasándole la dirección: const agent = new HttpsProxyAgent(proxyUrl). Crea una instancia de axios con la configuración mediante el método axios.create, pasándole httpsAgent igual a agent y httpAgent igual a agent.

Configuramos el manejo automático de cookies

Axios puro no sabe guardar las cookies de la respuesta en el almacén ni recuperarlas para la solicitud. Hay dos caminos.

  1. El primero: usar un envoltorio listo que conecte axios y tough-cookie; se instala como paquete aparte. Automáticamente lee y escribe cookies a través del almacén jar que se le pasa.
  2. El segundo: hacerlo manualmente mediante interceptores de solicitudes y respuestas. Antes de la solicitud, extraemos la cadena de cookies del almacén para la dirección correspondiente y la ponemos en el encabezado Cookie. Después de la respuesta, tomamos el encabezado Set-Cookie y guardamos cada cookie en el almacén.

Consejo: para empezar, usa el envoltorio listo: hay menos probabilidades de equivocarse. Deja el manual para cuando necesites controlar el proceso finamente, por ejemplo, para registrar cada cookie.

Aislamiento entre tareas paralelas

En Node.js el modelo es distinto: aquí no hay hilos, sino tareas asíncronas en un solo hilo de eventos. Pero el principio es el mismo: cada sesión lógica tiene su propio objeto client con su jar y su agente.

  1. Para cada tarea paralela, llama a makeClient por separado.
  2. Guarda los clientes en un arreglo o mapa, donde la clave sea el identificador de la tarea.
  3. Nunca uses un mismo jar para varios clientes al mismo tiempo.

⚠️ Atención: en código asíncrono es fácil compartir accidentalmente un client entre varias cadenas de promesas. Entonces las cookies empezarán a mezclarse entre sesiones lógicas. Comprueba siempre que cada cadena use su propio client, creado con una llamada separada a makeClient.

Rotación en Node.js

La lógica es idéntica a la de Python. Cuando necesitas una IP nueva y el servicio vincula la sesión a la dirección, crea un client nuevo con un proxy nuevo y un jar nuevo vacío, e inicia sesión de nuevo. Cuando el servicio lo tolera, transfiere el contenido del jar anterior al client nuevo con el agente nuevo.

Verificación: crea dos clientes con proxies diferentes. Haz solicitudes a un servicio de prueba que refleje la IP y las cookies. Asegúrate de que el primer cliente vea una IP y sus cookies, y el segundo, otra IP y las suyas. No debe haber cruces.

Paso 4: Almacenamiento del estado entre ejecuciones

Objetivo de la etapa: aprender a guardar cookies en disco y restaurarlas en la siguiente ejecución del programa, teniendo en cuenta su vida útil.

A menudo hay que detener el script y volver a ejecutarlo más tarde sin perder la autorización. Para eso, las cookies deben serializarse: convertirlas en texto y guardarlas en un archivo o base de datos.

Serialización en Python

El objeto CookieJar de requests se puede guardar de varias maneras. La más portable es reunir las cookies en un diccionario simple y escribirlo en formato JSON.

  1. Recorre todas las cookies del objeto de sesión a través de s.cookies.
  2. Para cada cookie, reúne su nombre, valor, dominio, ruta y fecha de expiración.
  3. Ponlos en una lista de diccionarios.
  4. Escribe la lista en un archivo en formato JSON.

Al restaurar, haz lo contrario: lee el archivo, recorre la lista y agrega cada cookie a un nuevo objeto de sesión mediante el método para establecer una cookie, indicando el dominio y la ruta.

Consejo: guarda junto con las cookies el identificador del proxy o al menos una marca que indique a qué sesión lógica pertenecen. Así no restaurarás cookies ajenas con una IP incorrecta ni violarás la regla de correspondencia.

Serialización en Node.js

La librería tough-cookie tiene un método de serialización integrado. El objeto jar tiene un método asíncrono que convierte todo el almacén en un objeto JSON. El método inverso restaura el jar a partir de ese objeto.

  1. Llama al método de serialización del almacén y obtén un objeto.
  2. Convierte el objeto en una cadena y guárdala en un archivo.
  3. Al iniciar, lee el archivo, convierte la cadena de nuevo en un objeto.
  4. Restaura el jar con el método de deserialización, pasándole el objeto.

Esto es más cómodo que en Python, porque tough-cookie guarda por sí solo todos los campos necesarios, incluida la fecha de expiración y las banderas de seguridad.

Vida útil de las cookies

Cada cookie tiene una fecha de expiración. Hay cookies de sesión: viven hasta que se cierra el navegador y no tienen una fecha explícita. Hay cookies persistentes: con una fecha de vencimiento concreta. Solo tiene sentido guardar en disco las cookies persistentes que aún no han caducado. Las cookies de sesión, después de reiniciar, por lo general ya no son válidas en el servidor.

  1. Antes de guardar, verifica la fecha de expiración de cada cookie.
  2. Descarta las que ya caducaron.
  3. Al restaurar, vuelve a revisar las fechas y no cargues las vencidas.

Cuándo es mejor descartar el estado

No siempre conviene aferrarse a las cookies guardadas. A veces un inicio limpio es más rápido y más confiable.

  • Si pasó mucho tiempo desde la última ejecución, la sesión en el servidor seguramente caducó; no hay nada que restaurar.
  • Si el servidor devolvió un error de autorización en la primera solicitud con las cookies restauradas, descártalas y vuelve a iniciar sesión.
  • Si no estás seguro de la integridad del archivo de estado, mejor empieza desde cero antes que depurar un comportamiento extraño.

⚠️ Atención: los archivos con cookies y tokens contienen datos de acceso. Guárdalos en un lugar protegido, no los subas a un repositorio público ni los envíes por canales no seguros. La filtración de un archivo así equivale a la filtración del acceso a la cuenta.

Verificación: guarda el estado, cierra el programa por completo, vuelve a ejecutarlo, restaura el estado y haz una solicitud que requiera autorización. Si el servidor responde como a un usuario autenticado, el guardado funciona. Si cierra la sesión, revisa las fechas de expiración y que hayas restaurado correctamente el dominio y la ruta.

Paso 5: Análisis de errores comunes en la arquitectura

Objetivo de la etapa: analizar en detalle los tres errores principales, para que los reconozcas en tu código y no los cometas.

Primer error: un CookieJar común para todos los proxies

Es la raíz del mal. El desarrollador crea un solo almacén de cookies y le asigna diferentes proxies pensando en ahorrar. ¿Qué pasa? Las cookies de la sesión en la primera IP llegan a la solicitud de la segunda IP. El servidor ve una cookie creada bajo otra dirección y, o cierra la sesión, o considera el comportamiento sospechoso.

La solución es simple: cada proxy, su propio almacén de cookies. Sin excepciones. Ya lo incorporamos en los pasos con código: una Session separada o un client separado con un jar propio para cada sesión lógica.

Segundo error: condición de carrera en solicitudes paralelas

Una condición de carrera es cuando dos operaciones acceden a los mismos datos al mismo tiempo y se estorban mutuamente. Si dos hilos escriben en un mismo CookieJar, una escritura puede sobrescribir a la otra. El resultado: parte de las cookies se pierde al azar, y el bug se reproduce de forma intermitente, lo que hace que sea angustiante depurarlo.

  1. Dale a cada hilo su propia sesión mediante los datos locales del hilo, como describimos.
  2. En código asíncrono, no compartas un client entre cadenas de tareas independientes.
  3. Si por alguna razón el objeto es compartido, usa un bloqueo para que solo un hilo trabaje con él a la vez.

Consejo: la mejor forma de evitar la condición de carrera es no tener datos mutables compartidos. El aislamiento por sesiones lógicas resuelve el problema de raíz: si los datos no son compartidos, no puede haber carrera.

Tercer error: pérdida de Set-Cookie en redirecciones

Cuando el servidor responde con una redirección, a menudo establece cookies importantes en esa misma respuesta mediante el encabezado Set-Cookie. Algunas configuraciones del cliente, al seguir automáticamente la redirección, pierden esas cookies: no llegan al almacén.

  1. Asegúrate de que tu cliente guarde las cookies en cada paso de la cadena de redirecciones, no solo en la respuesta final.
  2. En requests, esto funciona por defecto cuando usas el objeto Session: las cookies se recogen en el camino. Verifica que no hayas desactivado el seguimiento de redirecciones sin necesidad.
  3. En axios, cuando trabajas manualmente con cookies, procesa el Set-Cookie en cada respuesta intermedia. Si usas un envoltorio, verifica que intercepte las redirecciones.

⚠️ Atención: si la autorización funciona, pero la siguiente solicitud cierra la sesión, la causa frecuente es precisamente una cookie perdida en la redirección. Activa el registro de todos los encabezados Set-Cookie y revisa si todas las cookies esperadas llegaron al almacén.

Verificación: busca en el servicio objetivo una acción que provoque una redirección, por ejemplo, el inicio de sesión a través de un formulario. Recorre la cadena y compara las cookies después de cada paso. Todas las cookies emitidas deberían estar en tu almacén. Si falta alguna, encontraste la fuga.

Paso 6: Integramos todo en un flujo de trabajo

Objetivo de la etapa: unir lo aprendido en un flujo de trabajo único y predecible, desde el inicio hasta la rotación.

Ahora tienes todos los detalles. Vamos a unirlos en una cadena de acciones que puedas repetir.

  1. Toma un proxy de tu pool y crea una sesión lógica aislada para él: una Session en Python o un client en Node.js.
  2. Si hay un estado guardado para esa sesión lógica y no ha caducado, restaura las cookies. Si no, inicia sesión de nuevo.
  3. Haz las solicitudes necesarias a través del objeto de esa sesión. Las cookies se acumulan automáticamente.
  4. Guarda el estado en disco periódicamente para no perder el progreso ante un fallo.
  5. Cuando llegue el momento de rotar la IP, finaliza la sesión lógica de forma correcta.
  6. Si el servicio está rígidamente vinculado a la IP, comienza una nueva sesión lógica desde cero en la nueva dirección.
  7. Si el servicio lo tolera, crea un contenedor nuevo con el nuevo proxy y transfiere a él las cookies del anterior.

Consejo: lleva un registro de eventos: cuándo se creó la sesión, con qué IP, cuándo ocurrió la rotación, si hubo cierre de sesión. Ese registro mostrará en cinco minutos un patrón que de otra manera buscarías durante horas.

Verificación: ejecuta el ciclo completo: creación de sesión, autorización, algunas acciones, guardado, rotación, continuación. Asegúrate de que en cada paso el estado se comporte de forma predecible y que el cierre de sesión ocurra solo cuando lo esperas.

Verificación del resultado: lista de verificación final

Repasa esta lista. Si todos los puntos se cumplen, tu sistema funciona correctamente.

  • Cada sesión lógica tiene un objeto contenedor separado con su propio almacén de cookies.
  • A cada contenedor está vinculado exactamente un proxy durante toda la vida de la sesión.
  • No hay ningún lugar donde las cookies de una sesión puedan pasar a otra.
  • En código multihilo, cada hilo usa su propia sesión mediante los datos locales del hilo.
  • En código asíncrono, cada cadena independiente tiene su propio client.
  • Las cookies se recogen correctamente en todos los pasos de las redirecciones.
  • El estado se guarda y se restaura entre ejecuciones, teniendo en cuenta las fechas de expiración.
  • Al cambiar de IP, la sesión lógica o bien comienza de nuevo, o bien las cookies se transfieren de forma consciente.
  • Los archivos con cookies y tokens se guardan de forma segura.

Cómo probarlo

  1. Encuentra un servicio de prueba que muestre tu IP actual y las cookies enviadas.
  2. Crea dos sesiones con proxies diferentes y verifica el aislamiento total de los datos.
  3. Inicia sesión, guarda el estado, reinicia el programa, restaura el estado y comprueba que la autorización sigue viva.
  4. Simula una rotación y observa cómo se comporta la sesión.

Indicadores de éxito: los datos de diferentes sesiones nunca se mezclan, el cierre de sesión ocurre solo cuando hay una vinculación estricta del servidor a la IP, el estado restaurado funciona y no hay condiciones de carrera en el trabajo paralelo.

Errores típicos y soluciones

Problema: después de cambiar de IP, la sesión del usuario se cierra. Causa: el servidor vincula la sesión rígidamente a la dirección. Solución: no cambiar la IP dentro de una misma sesión lógica, y si es necesario cambiarla, iniciar una sesión nueva en la nueva dirección.

Problema: las cookies de diferentes sesiones se mezclan. Causa: un CookieJar común para varios proxies. Solución: dar a cada sesión lógica un almacén separado y nunca compartirlo.

Problema: el bug aparece de forma intermitente en el trabajo paralelo. Causa: condición de carrera al escribir en un objeto compartido desde varios hilos. Solución: aislar las sesiones por hilos mediante datos locales del hilo o usar un bloqueo.

Problema: la autorización funciona, pero inmediatamente se cae. Causa: pérdida de una cookie en la redirección. Solución: revisar la recolección de cookies en todos los pasos de la cadena de redirecciones y activar el registro de Set-Cookie.

Problema: el estado restaurado no funciona. Causa: se guardaron cookies vencidas o de sesión, o se indicaron incorrectamente el dominio y la ruta. Solución: guardar solo las cookies persistentes vigentes y restaurarlas con el dominio y la ruta correctos.

Problema: el token CSRF es constantemente inválido. Causa: se perdió la cookie de sesión a la que está vinculado el token. Solución: primero restaurar la integridad de las cookies de sesión; el token se cargará automáticamente.

Problema: el JWT deja de funcionar después de la rotación. Causa: un servicio específico vinculó el token a la IP en su lado. Solución: no cambiar la IP durante la vida del token u obtener un token nuevo en la nueva dirección.

Opciones adicionales y optimización

Cuando el esquema básico funciona, puedes mejorarlo.

Pool de sesiones listas

En lugar de crear una sesión cada vez, mantén un pool de sesiones lógicas ya preparadas y autorizadas, cada una con su proxy. Toma una sesión libre, úsala, devuélvela al pool. Esto acelera el trabajo porque la autorización no se repite innecesariamente.

Verificación automática de vigencia

Agrega una función que haga una solicitud ligera al servicio y verifique si la sesión está viva. Si el servidor responde como a un usuario no autenticado, la sesión se marca para volver a autorizarse. Así detectas la caducidad antes de que arruine una operación importante.

Consejo: no hagas la verificación de vigencia antes de cada solicitud, sino según un horario o después de pausas largas. Las verificaciones demasiado frecuentes generan carga innecesaria y no aportan beneficio.

Almacén centralizado de estados

Para proyectos grandes, en lugar de archivos usa una base de datos como almacén de cookies. La clave es el identificador de la sesión lógica; el valor, el estado serializado. Es más fácil de escalar y más seguro de guardar.

Métricas y observabilidad

Cuenta cuántas veces ocurre un cierre de sesión, cuántas sesiones hubo que recrear, con qué frecuencia la restauración tiene éxito. Estas cifras muestran la salud de tu sistema y señalan dónde algo está configurado de forma no óptima.

FAQ: preguntas frecuentes

¿Es obligatorio crear un nuevo objeto de sesión en cada cambio de IP? Si el servicio verifica la dirección de forma estricta, sí, porque la sesión anterior en la nueva IP de todos modos no será aceptada. Si el servicio lo tolera, puedes transferir las cookies a un contenedor nuevo con el nuevo proxy y continuar.

¿Se puede usar un mismo proxy para varias sesiones lógicas? Desde el punto de vista del código se puede, pero cada sesión lógica igual debe tener su propio almacén de cookies. Solo pueden ser comunes los ajustes de conexión, pero no el estado.

¿Por qué no se pueden guardar todas las cookies en un solo lugar y filtrarlas por dominio? Porque el problema no es el dominio, sino la vinculación a una sesión lógica y una IP específicas. Las cookies de una sesión en un dominio no deben llegar a otra sesión en el mismo dominio.

¿Cómo saber si el servicio vincula la sesión a la IP? Haz un experimento: inicia sesión en una IP, cambia de dirección y haz una solicitud. Si cerró la sesión, probablemente hay vinculación. Vuelve a la IP anterior: si se restauró, significa que el servidor recuerda la primera dirección.

¿Qué hacer con las cookies de sesión al guardarlas en disco? Por lo general no tiene sentido guardarlas, porque el servidor las considera inválidas después de interrumpir la conexión. Guarda las cookies persistentes con una fecha vigente.

¿Qué hacer si la librería no guarda las cookies por sí sola en la redirección? Procesa manualmente el encabezado Set-Cookie en cada respuesta intermedia de la cadena de redirecciones y coloca las cookies en tu almacén.

¿Se necesita un bloqueo si cada hilo tiene su propia sesión? No. Si los datos no son compartidos, no puede haber una condición de carrera, y el bloqueo no es necesario. El bloqueo solo se requiere cuando hay acceso compartido forzoso a un mismo objeto.

¿Cuánto tiempo se puede conservar el estado restaurable? Exactamente hasta que el servidor considere viva la sesión. El plazo exacto depende del servicio. Es más práctico verificar la vigencia con una solicitud que adivinar por tiempo.

¿Qué es más importante: guardar las cookies o guardar el token? Depende del mecanismo de autorización del servicio. A veces basta con el token; a veces se necesita el conjunto completo de cookies. Es más seguro guardar todo el estado por completo; así no perderás lo necesario.

¿Se pueden transferir cookies entre Python y Node.js? Sí, si se guardan en un formato neutral común como JSON con los campos de nombre, valor, dominio, ruta y fecha. Así cualquiera de los sistemas podrá leerlas.

Conclusión

Hagamos un resumen de lo que has recorrido. Entendiste que después de cambiar de IP, el cierre de sesión no ocurre por el simple hecho del cambio, sino por las verificaciones del servidor y los errores en tu arquitectura. Aprendiste que las cookies, el CSRF y el JWT por sí solos no están vinculados a la dirección; la vinculación la agrega un servicio específico. Asimilaste la regla principal: una sesión lógica equivale a un conjunto de cookies, que equivale a una IP.

Luego escribiste código funcional. En Python, mediante un objeto Session separado con su propio CookieJar para cada proxy y aislamiento por hilos. En Node.js, mediante la combinación de axios, tough-cookie y un agente proxy, con un client separado para cada sesión lógica. Aprendiste a guardar el estado entre ejecuciones, a tener en cuenta las fechas de expiración de las cookies y a entender cuándo es mejor descartar el estado.

Analizaste tres errores traicioneros: un CookieJar común, la condición de carrera en el trabajo paralelo y la pérdida de Set-Cookie en las redirecciones. Ahora tienes una lista de verificación previa a producción que no permitirá lanzar una solución a medio hacer.

Qué hacer a continuación

Empieza poco a poco. Toma un escenario real, implementa para él una sesión lógica aislada y asegúrate de que el estado no se pierda. Luego agrega el guardado en disco. Después, escala a varias sesiones. Avanza paso a paso, verificando el resultado en cada uno.

Hacia dónde avanzar

Después conviene profundizar en la observabilidad: configurar métricas de vigencia de sesiones y registro de eventos. Luego estudiar cómo transferir el estado de forma consciente cuando el servicio tolera el cambio de dirección. Y, por último, construir un pool de sesiones listas para acelerar el trabajo. Cada uno de estos pasos hace que tu sistema sea más estable y predecible. Lo lograrás: ya entendiste el principio; el resto es cuestión de práctica.