Como manter sessão, cookies e tokens ao rotacionar IP: guia passo a passo
Sumário do artigo
- Introdução: por que a troca de ip desloga e o carrinho esvazia
- Preparação inicial: ferramentas e ambiente
- Conceitos básicos: o que está vinculado ao ip e o que é mito
- Passo 1: definindo a regra de correspondência
- Passo 2: na prática com python — uma session para cada proxy
- Passo 3: o mesmo no node.js
- Passo 4: armazenando o estado entre execuções
- Passo 5: análise dos erros mais comuns na arquitetura
- Passo 6: juntando tudo em um fluxo de trabalho
- Verificação do resultado: checklist final
- Erros típicos e soluções
- Recursos adicionais e otimização
- Faq: perguntas frequentes
- Conclusão
Você certamente já passou por isso: o script funciona, autentica no site, coloca o produto no carrinho, e então o IP muda e, de repente, o servidor responde como se você fosse um visitante de primeira viagem. O usuário está deslogado, o carrinho vazio, o token inválido. Irritante? Muito. Mas esse problema tem uma solução de engenharia clara, e neste guia vamos analisá-la do início ao fim.
Introdução: por que a troca de IP desloga e o carrinho esvazia
Sendo honestos: quando a sessão cai após a rotação de IP, o primeiro instinto é culpar o próprio fato da troca de endereço. Tipo: o IP mudou, o servidor percebeu e resetou tudo. Às vezes é isso mesmo. Mas, na maioria das vezes, o problema não está no IP em si, e sim em como o seu código funciona. Ele mistura o estado de sessões diferentes, perde cookies e envia tokens antigos a partir de um novo endereço. Vamos aprender a evitar que isso aconteça.
O que o leitor vai conquistar no final
Ao final deste guia, você será capaz de: primeiro, entender o que está realmente vinculado ao IP no lado do servidor e o que é mito. Segundo, estabelecer uma regra estrita de correspondência: uma sessão lógica é igual a um conjunto de cookies e igual a um IP. Terceiro, escrever código funcional em Python e Node.js que isola o estado entre diferentes proxies e não mistura dados. Quarto, salvar o estado entre execuções do programa e saber quando é mais simples descartá-lo.
Para quem é este guia
O guia é voltado para o nível intermediário. Você já escreve código em Python ou JavaScript, sabe o que é uma requisição HTTP e tem ideia de para que servem os proxies. Não vamos discutir qual tipo de rotação escolher — para isso existem materiais específicos. Aqui, partimos do princípio de que a rotação de IP já acontece conforme as suas regras, e resolvemos exatamente um problema: como não perder o estado durante essa rotação.
O que você precisa saber de antemão
É útil entender o básico. O que é cookie — é um pequeno pedaço de dado que o servidor pede para o navegador ou cliente guardar e enviar de volta em cada requisição. O que é sessão — é a forma de o servidor reconhecer você entre requisições. O que é token — é uma string que confirma a sua identidade ou o direito de realizar uma ação. Se esses termos ainda estão confusos, não se preocupe: na seção de conceitos básicos, vamos explicar cada um de forma simples.
Quanto tempo você vai precisar
A leitura e a compreensão da teoria levam cerca de quarenta minutos. Analisar e executar o código na sua linguagem leva de uma a uma hora e meia. A assimilação completa com experimentos em tarefas reais leva de duas a três horas. Não tenha pressa. É melhor entender o princípio devagar do que copiar rapidamente um código que depois vai quebrar de um jeito estranho.
Preparação inicial: ferramentas e ambiente
Antes de escrever código, vamos organizar o ambiente de trabalho. Isso vai levar pouco tempo, mas economizará horas de depuração depois.
Ferramentas necessárias
- Python 3.10 ou mais recente — se você trabalha com Python. Em 2026, as versões 3.12 e 3.13 são as mais usadas, mas tudo o que descrevermos funciona a partir da 3.10.
- Node.js 20 LTS ou mais recente — se você trabalha com JavaScript. A versão 22 LTS também serve.
- Proxy com rotação de IP — você já deve ter acesso a um pool de endereços. O formato de conexão normalmente é: protocolo, host, porta, login e senha.
- Editor de código — qualquer um serve, por exemplo, um editor gratuito com realce de sintaxe.
- Terminal ou prompt de comando — para instalar bibliotecas e executar scripts.
Requisitos de sistema
Os requisitos são modestos. Qualquer computador moderno dá conta. Quatro gigabytes de RAM são suficientes, mas, se você planeja muitas sessões paralelas, é melhor ter oito ou mais. O mais importante é uma conexão de internet estável, porque, se a conexão cair, os cookies podem não ser salvos corretamente.
O que é preciso instalar
Para Python, instale duas bibliotecas. Abra o terminal e execute o comando de instalação do pacote requests e do pacote para trabalhar com proxy. Faça assim: primeiro o comando de instalação do gerenciador de pacotes, depois o nome requests. Para a serialização do estado, o módulo padrão resolve — não é preciso instalar nada separado.
Para Node.js, instale três pacotes: axios para requisições, tough-cookie para gerenciar o armazenamento de cookies e https-proxy-agent para conectar via proxy. Os três são instalados com um único comando de instalação de pacotes no seu projeto.
Dica: Crie uma pasta virtual separada para o projeto. No Python, use um ambiente virtual; no Node.js, uma pasta separada com um arquivo de descrição de dependências. Assim, você não mistura bibliotecas de projetos diferentes e evita conflitos de versão.
Criando backups
Se você já salva cookies em arquivos ou banco de dados, faça uma cópia antes dos experimentos. Vamos mudar a lógica de serialização e há risco de danificar os dados existentes. É só copiar a pasta com os estados salvos para um local marcado como backup.
Verificação: Depois da instalação, confirme que está tudo funcionando. Execute uma checagem rápida da versão do Python ou Node.js no terminal. Você deve ver o número da versão sem erros. Depois, tente importar as bibliotecas instaladas no modo interativo — se a importação passar sem mensagens, está tudo pronto.
Conceitos básicos: o que está vinculado ao IP e o que é mito
Esta é a seção teórica mais importante. Enquanto você não entender o que está realmente ligado ao IP, vai tratar a doença errada. Vamos passar pelos tipos de dados um a um.
Sessão por cookie
Sessão por cookie é quando o servidor fornece um identificador de sessão em forma de cookie e guarda o estado do lado dele. Por exemplo, um cookie chamado sessionid com uma longa string aleatória dentro. O servidor usa essa string para encontrar o seu registro na memória dele. Esse mecanismo está vinculado ao IP? Por si só, não. O cookie funciona independentemente do endereço. Mas muitos serviços adicionam uma verificação extra: eles lembram de qual IP a sessão foi criada e, se uma requisição com o mesmo cookie vier de outro endereço, consideram suspeito. É aí que acontece o logout.
Token CSRF
O token CSRF é uma proteção contra falsificação de requisições. O servidor emite um token, e você precisa enviá-lo de volta ao enviar um formulário ou executar uma ação importante. Esse token quase nunca está vinculado ao IP. Ele está ligado à sessão, não ao endereço. O problema com ele surge por outro motivo: se você perdeu o cookie da sessão, o token CSRF também se torna inválido, porque o servidor não consegue associá-lo à sua sessão. Ou seja, o problema aqui é secundário — uma consequência da perda dos cookies.
JWT
JWT é um token que carrega informações dentro dele e é assinado pelo servidor. O cliente o armazena e o envia no cabeçalho de cada requisição. O JWT clássico não é vinculado ao IP de forma alguma. Ele é autossuficiente: o servidor verifica a assinatura e a validade, e o endereço não importa. Mas existem implementações em que o servidor guarda a vinculação do token ao IP do lado dele ou coloca o endereço dentro do token. Nesses casos, a troca de IP quebra a verificação. Isso não é uma propriedade do JWT, e sim uma decisão do serviço específico.
Sessão no servidor
Sessão no servidor é o nome genérico para o estado que o servidor guarda e associa ao seu identificador. Carrinho, histórico de visualização, status de autenticação — tudo isso costuma ficar na sessão do servidor. A vinculação ao IP aqui depende das configurações do serviço. Alguns, por segurança, vinculam a sessão ao primeiro IP de forma rígida. Outros toleram a troca de endereço. Normalmente você não sabe de antemão, então é mais seguro construir o código como se a vinculação existisse — essa é uma estratégia segura.
Carrinho de compras
O carrinho de compras é um caso específico de sessão no servidor ou de cookie. Em lojas simples, o carrinho fica em um cookie no lado do cliente. Em lojas complexas, fica no servidor, vinculado à sessão. Se o carrinho esvazia depois da troca de IP, isso significa que ele estava vinculado a uma sessão no servidor que verifica o endereço. A solução é a mesma: não troque de IP dentro de uma mesma sessão lógica ou salve cuidadosamente o conjunto completo de cookies.
Resumo: onde o IP realmente entra
Vamos montar o quadro. O mecanismo HTTP de cookies, CSRF e JWT não é vinculado ao IP. A vinculação surge como uma verificação extra do lado do serviço, e você não consegue gerenciá-la. A única coisa que você controla é a correspondência entre sessão, conjunto de cookies e IP do seu lado. Daí vem a regra principal deste guia.
Verificação: Teste seu entendimento. Se depois da troca de IP a sessão cair, mas ao voltar para o IP antigo tudo se restabelecer, o servidor está verificando o endereço de forma rígida. Se não se restabelecer nem no IP antigo, você simplesmente perdeu os cookies no código. São dois diagnósticos diferentes, com tratamentos diferentes.
Passo 1: Definindo a regra de correspondência
Objetivo da etapa: fixar o princípio principal e entender como expressá-lo na estrutura do código.
A regra é simples: uma sessão lógica é igual a um conjunto de cookies e igual a um IP. Vamos entender o que isso significa na prática.
- Uma sessão lógica é uma sequência de requisições que representa um trabalho contínuo: você entrou, autenticou, fez algo, saiu. Tudo isso é uma única sessão lógica.
- Um conjunto de cookies é um armazenamento separado de cookies que pertence apenas a essa sessão lógica e a mais ninguém.
- Um IP: durante uma mesma sessão lógica, o endereço não muda. Se a rotação acontecer mesmo assim, a sessão lógica é considerada encerrada.
Como expressar isso no código? De forma bem visual: criamos um objeto contêiner que guarda dentro dele tanto o armazenamento de cookies quanto a configuração do proxy. Enquanto esse objeto existe, a sessão lógica existe. Quando for hora de trocar de IP, ou criamos um novo contêiner ou, se o serviço tolerar a troca de endereço, transferimos os cookies com cuidado para um novo contêiner com o novo IP.
⚠️ Atenção: O erro arquitetural mais comum é manter um único conjunto de cookies e usar proxies diferentes com ele. Isso com certeza quebra tudo. Sessões lógicas diferentes começam a sobrescrever os cookies umas das outras, e o servidor recebe dados contraditórios. Nunca faça isso.
Dica: Pense na sessão lógica como se fosse uma pessoa. Uma pessoa tem um documento (cookies) e uma casa (IP). Não dá para duas pessoas usarem o mesmo documento, e não dá para uma pessoa morar em duas casas ao mesmo tempo. Essa analogia vai te proteger da maioria dos erros.
Verificação: Desenhe no papel a sua futura estrutura. Você deve ter vários blocos independentes, cada um com seu armazenamento de cookies e seu proxy. Não há dados compartilhados entre os blocos. Se é assim, você entendeu a regra.
Passo 2: Na prática com Python — uma Session para cada proxy
Objetivo da etapa: escrever um código funcional em que cada sessão lógica tenha seu próprio objeto requests.Session, seu próprio CookieJar e seu próprio proxy, isolados entre si.
Na biblioteca requests, existe o objeto Session. Ele por si só é um contêiner: guarda internamente o armazenamento de cookies e consegue aplicar configurações a todas as requisições. É a base ideal para a nossa sessão lógica.
Estrutura básica
- Crie uma função que receba os dados de um proxy e retorne um objeto Session pronto.
- Dentro da função, crie um novo objeto Session.
- Defina a configuração proxies no objeto — um dicionário com o endereço do proxy para os protocolos http e https.
- Retorne o objeto. Agora você tem um contêiner isolado.
O código fica assim. Passo a passo: importamos o requests. Definimos a função make_session, que recebe uma string proxy_url. Dentro, escrevemos s = requests.Session(). Em seguida, s.proxies é igual a um dicionário em que a chave http aponta para proxy_url e a chave https aponta para proxy_url. No final, return s. Pronto, a função está pronta.
Por que isso isola o estado
Cada chamada a make_session cria um objeto completamente novo. O novo objeto tem seu próprio armazenamento interno de cookies, chamado cookiejar. Cookies obtidos por uma sessão não têm como chegar a outra sessão, porque são objetos diferentes na memória. É exatamente isso que queríamos.
Usando a sessão
- Obtenha o objeto de sessão chamando a função com o proxy desejado.
- Faça as requisições pelos métodos desse objeto: s.get ou s.post.
- Cookies que o servidor enviar no cabeçalho Set-Cookie são salvos automaticamente dentro do objeto.
- Nas próximas requisições pelo mesmo objeto, esses cookies são enviados de volta automaticamente.
Dica: Não crie uma nova Session para cada requisição dentro da mesma sessão lógica. Assim, os cookies não vão se acumular. Crie o objeto uma única vez para a sessão lógica inteira e use-o em todas as requisições dessa sessão.
Isolamento entre threads
Se você trabalha com várias threads, cada thread precisa ter seu próprio objeto Session. O objeto Session não é seguro para uso entre threads. Isso significa que, se duas threads escrevem cookies no mesmo objeto ao mesmo tempo, os dados podem ser corrompidos.
- Use o mecanismo de dados locais da thread. No Python, isso é o objeto threading.local.
- Ao iniciar cada thread, crie uma sessão separada para ela e guarde-a no armazenamento local da thread.
- Dentro da thread, acesse apenas a sua sessão, sem tocar nas outras.
Na prática, fica assim: criamos um objeto global local = threading.local(). No início do trabalho da thread, verificamos se local tem o atributo session. Se não tiver, criamos com make_session usando o proxy designado para aquela thread. A partir daí, dentro da thread, usamos local.session para todas as requisições.
⚠️ Atenção: Nunca compartilhe um único objeto Session entre threads como um recurso comum. Mesmo que pareça que as requisições acontecem em sequência, o escalonador pode alternar as threads no pior momento, e você vai acabar com cookies misturados. Para cada thread, um objeto próprio.
Rotação na lógica
Quando a rotação de IP acontece e você precisa de um novo endereço, faça o seguinte. Encerre a sessão lógica atual: se o servidor vincula rigidamente ao IP, basta criar um novo objeto Session com o novo proxy e começar do zero — autentique-se novamente. Se o servidor tolera a troca de endereço, você pode transferir os cookies, como veremos no passo sobre armazenamento de estado.
Verificação: Execute duas sessões com proxies diferentes e autentique-se em cada uma em um serviço de teste que mostre seu IP e cookies. Confirme que cada sessão vê seu próprio IP e seu próprio conjunto de cookies. Se os dados não se misturam, a isolação está funcionando corretamente.
Passo 3: O mesmo no Node.js
Objetivo da etapa: montar a construção equivalente em JavaScript usando axios, tough-cookie e o agente de proxy.
No ecossistema do Node.js não existe um objeto Session pronto como esse, então vamos montá-lo a partir de três partes. O armazenamento de cookies vem do tough-cookie. A conexão via proxy fica por conta do agente. As requisições serão feitas pelo axios.
Montando o contêiner
- Importe a classe CookieJar da biblioteca tough-cookie.
- Importe a função de criação do agente de proxy da biblioteca https-proxy-agent.
- Importe o axios.
- Crie a função makeClient, que recebe o endereço do proxy e retorna um objeto configurado.
Dentro da função, crie uma nova instância do armazenamento: const jar = new CookieJar(). Crie o agente de proxy passando o endereço: const agent = new HttpsProxyAgent com o endereço do proxy. Crie uma instância do axios com as configurações pelo método axios.create, passando httpsAgent igual a agent e httpAgent igual a agent.
Ativando o trabalho automático com cookies
O axios puro não sabe colocar cookies da resposta no armazenamento nem buscá-los para a requisição. Existem dois caminhos.
- Primeiro caminho: usar uma wrapper pronta que conecta axios e tough-cookie, instalada como pacote separado. Ela lê e escreve cookies automaticamente por meio do armazenamento jar informado.
- Segundo caminho: fazer isso manualmente com interceptadores de requisições e respostas. Antes da requisição, pegamos a string de cookies do armazenamento para o endereço desejado e colocamos no cabeçalho Cookie. Depois da resposta, pegamos o cabeçalho Set-Cookie e gravamos cada cookie no armazenamento.
Dica: Para começar, use a wrapper pronta — menos chance de errar. Deixe o método manual para quando precisar de controle fino, por exemplo, para registrar cada cookie.
Isolamento entre tarefas paralelas
No Node.js, o modelo é diferente — aqui não temos threads, e sim tarefas assíncronas em um único loop de eventos. Mas o princípio é o mesmo: cada sessão lógica tem seu próprio objeto client, com seu próprio jar e seu próprio agente.
- Para cada tarefa paralela, chame makeClient separadamente.
- Guarde os clientes em um array ou mapa, em que a chave é o identificador da tarefa.
- Nunca use um mesmo jar para vários clientes ao mesmo tempo.
⚠️ Atenção: Em código assíncrono, é fácil, sem querer, compartilhar um mesmo client entre várias cadeias de promessas. Aí os cookies começam a se misturar entre sessões lógicas. Sempre confira se cada cadeia usa o próprio client, criado por uma chamada separada a makeClient.
Rotação no Node.js
A lógica é idêntica à do Python. Quando você precisa de um novo IP e o serviço vincula a sessão ao endereço, crie um novo client com o novo proxy e um jar vazio novo, e autentique-se de novo. Quando o serviço tolera, transfira o conteúdo do jar antigo para o novo client com o novo agente.
Verificação: Crie dois clientes com proxies diferentes. Faça requisições a um serviço de teste que mostre IP e cookies. Confirme que o primeiro cliente vê um IP e os próprios cookies, e o segundo vê outro IP e os próprios cookies. Não pode haver interseção.
Passo 4: Armazenando o estado entre execuções
Objetivo da etapa: aprender a salvar cookies no disco e restaurá-los na próxima execução do programa, levando em conta o prazo de validade.
Muitas vezes você precisa parar o script e executá-lo de novo depois, sem perder a autenticação. Para isso, é preciso serializar os cookies — transformá-los em texto e salvá-los em um arquivo ou banco de dados.
Serialização no Python
O objeto CookieJar do requests pode ser salvo de várias formas. A mais portável é reunir os cookies em um dicionário simples e gravar no formato JSON.
- Percorra todos os cookies do objeto de sessão usando s.cookies.
- Para cada cookie, colete o nome, o valor, o domínio, o caminho e o prazo de validade.
- Coloque tudo em uma lista de dicionários.
- Grave a lista em um arquivo no formato JSON.
Para restaurar, faça o caminho inverso: leia o arquivo, percorra a lista e adicione cada cookie a um novo objeto de sessão usando o método de definição de cookie, informando domínio e caminho.
Dica: Guarde junto com os cookies o identificador do proxy ou pelo menos uma marcação de a qual sessão lógica eles pertencem. Assim, você não vai restaurar cookies de outra sessão com o IP errado e não vai violar a regra de correspondência.
Serialização no Node.js
A biblioteca tough-cookie tem um método de serialização embutido. O objeto jar tem um método assíncrono que transforma todo o armazenamento em um objeto JSON. O método inverso restaura o jar a partir desse objeto.
- Chame o método de serialização do armazenamento e obtenha o objeto.
- Transforme o objeto em string e salve em um arquivo.
- Ao iniciar, leia o arquivo e transforme a string de volta em objeto.
- Restaure o jar com o método de desserialização, passando o objeto.
Isso é mais conveniente do que no Python, porque o próprio tough-cookie guarda todos os campos necessários, incluindo prazo de validade e flags de segurança.
Prazo de validade dos cookies
Cada cookie tem um prazo de validade. Existem cookies de sessão — eles vivem até o navegador fechar e não têm data explícita. Existem cookies permanentes — com uma data de expiração específica. Só faz sentido salvar no disco cookies permanentes que ainda não expiraram. Cookies de sessão normalmente já estão inválidos no servidor depois de uma reinicialização.
- Antes de salvar, verifique a data de expiração de cada cookie.
- Descarte os que já expiraram.
- Ao restaurar, verifique os prazos de novo e não carregue cookies vencidos.
Quando é mais simples descartar o estado
Nem sempre vale a pena se agarrar aos cookies salvos. Às vezes, começar do zero é mais rápido e mais confiável.
- Se passou muito tempo desde a última execução, a sessão no servidor provavelmente expirou — não há o que restaurar.
- Se o servidor retornou erro de autenticação já na primeira requisição com os cookies restaurados, descarte-os e autentique-se novamente.
- Se você não tem certeza da integridade do arquivo de estado, é melhor começar do zero do que depurar um comportamento estranho.
⚠️ Atenção: Arquivos com cookies e tokens contêm dados de acesso. Guarde-os em um local seguro, não os envie para um repositório público e não os transmita por canais não seguros. O vazamento de um arquivo desses equivale ao vazamento de acesso à conta.
Verificação: Salve o estado, feche completamente o programa, execute-o novamente, restaure o estado e faça uma requisição que exija autenticação. Se o servidor responder como se você estivesse autenticado, o salvamento está funcionando. Se deslogar, verifique os prazos de validade e se o domínio e o caminho foram restaurados corretamente.
Passo 5: Análise dos erros mais comuns na arquitetura
Objetivo da etapa: analisar os três principais erros em detalhes para você reconhecê-los no seu código e não cometê-los.
Erro número um: um CookieJar compartilhado para todos os proxies
Essa é a raiz do mal. O desenvolvedor cria um único armazenamento de cookies e usa proxies diferentes com ele, achando que vai economizar. O que acontece: cookies da sessão no primeiro IP vão parar na requisição do segundo IP. O servidor vê um cookie criado para outro endereço e ou derruba a sessão, ou considera o comportamento suspeito.
A solução é simples: para cada proxy, um armazenamento de cookies separado. Sem exceções. Já deixamos isso definido nos passos de código: uma Session separada ou um client separado com um jar separado para cada sessão lógica.
Erro número dois: corrida em requisições paralelas
Corrida é quando duas operações acessam os mesmos dados ao mesmo tempo e atrapalham uma à outra. Se duas threads escrevem no mesmo CookieJar, uma gravação pode sobrescrever a outra. O resultado: parte dos cookies se perde de forma aleatória, e o bug se reproduz de vez em quando, o que é um tormento para depurar.
- Dê a cada thread sua própria sessão usando os dados locais da thread, como descrevemos.
- No código assíncrono, não compartilhe um mesmo client entre cadeias de tarefas independentes.
- Se por algum motivo o objeto for compartilhado mesmo assim, use um bloqueio para que apenas uma thread trabalhe com ele por vez.
Dica: A melhor forma de evitar corrida é simplesmente não ter dados mutáveis compartilhados. O isolamento por sessões lógicas resolve o problema na raiz: se os dados não são compartilhados, não existe corrida.
Erro número três: perda de Set-Cookie em redirecionamentos
Quando o servidor responde com um redirecionamento, muitas vezes ele define cookies importantes nessa mesma resposta, via cabeçalho Set-Cookie. Algumas configurações de cliente perdem esses cookies ao seguir o redirecionamento automaticamente — eles não chegam ao armazenamento.
- Confirme que seu cliente salva cookies em cada etapa da cadeia de redirecionamentos, e não apenas na resposta final.
- No requests, isso funciona por padrão quando você usa o objeto Session — os cookies são coletados pelo caminho. Verifique se você não desativou o seguimento de redirecionamentos sem necessidade.
- No axios, ao trabalhar com cookies manualmente, processe o Set-Cookie em cada resposta intermediária. Se usar uma wrapper, confirme que ela intercepta os redirecionamentos.
⚠️ Atenção: Se a autenticação funciona, mas a próxima requisição desloga, a causa mais comum é exatamente um cookie perdido no redirecionamento. Ative o registro de todos os cabeçalhos Set-Cookie e veja se todos os cookies esperados chegaram ao armazenamento.
Verificação: Encontre no serviço de destino uma ação que gere redirecionamento, como um login por formulário. Acompanhe a cadeia e compare os cookies depois de cada etapa. Todos os cookies emitidos devem estar no seu armazenamento. Se algum sumiu, você encontrou o vazamento.
Passo 6: Juntando tudo em um fluxo de trabalho
Objetivo da etapa: unir o que foi aprendido em um fluxo de trabalho único e previsível, do início à rotação.
Agora você tem todas as peças. Vamos montá-las em uma sequência de ações que pode ser repetida.
- Pegue um proxy do seu pool e crie uma sessão lógica isolada para ele — uma Session no Python ou um client no Node.js.
- Se houver um estado salvo para essa sessão lógica e ele não estiver vencido, restaure os cookies. Caso contrário, autentique-se novamente.
- Faça as requisições necessárias pelo objeto dessa sessão. Os cookies vão se acumulando automaticamente.
- Salve o estado periodicamente no disco para não perder o progresso em caso de falha.
- Quando chegar a hora da rotação de IP, encerre a sessão lógica corretamente.
- Se o serviço for rigidamente vinculado ao IP, inicie uma nova sessão lógica do zero no novo endereço.
- Se o serviço tolerar, crie um novo contêiner com o novo proxy e transfira para ele os cookies do antigo.
Dica: Mantenha um registro de eventos: quando a sessão foi criada, com qual IP, quando a rotação aconteceu, se houve logout. Esse registro mostra em cinco minutos um padrão que você levaria horas procurando.
Verificação: Execute o ciclo completo: criação de sessão, autenticação, algumas ações, salvamento, rotação e continuação. Garanta que, em cada etapa, o estado se comporte de forma previsível e que o logout aconteça somente quando você espera.
Verificação do resultado: checklist final
Percorra esta lista. Se todos os itens forem cumpridos, o seu sistema está funcionando corretamente.
- Cada sessão lógica tem um objeto contêiner separado, com seu próprio armazenamento de cookies.
- A cada contêiner está vinculado exatamente um proxy durante toda a vida da sessão.
- Não há nenhum lugar em que cookies de uma sessão possam ir parar em outra.
- No código multithread, cada thread usa a própria sessão por meio dos dados locais da thread.
- No código assíncrono, cada cadeia independente tem o seu próprio client.
- Os cookies são coletados corretamente em todas as etapas dos redirecionamentos.
- O estado é salvo e restaurado entre execuções, levando em conta os prazos de validade.
- Na troca de IP, a sessão lógica ou começa de novo, ou os cookies são transferidos de forma consciente.
- Os arquivos com cookies e tokens ficam armazenados com segurança.
Como testar
- Encontre um serviço de teste que mostre seu IP atual e os cookies recebidos.
- Crie duas sessões com proxies diferentes e confirme o isolamento total dos dados.
- Autentique-se, salve o estado, reinicie o programa, restaure e verifique se a autenticação continua viva.
- Simule uma rotação e observe como a sessão se comporta.
Indicadores de sucesso: os dados de sessões diferentes nunca se misturam, o logout só ocorre quando há vinculação rígida do servidor ao IP, o estado restaurado funciona e não há corridas no trabalho paralelo.
Erros típicos e soluções
Problema: depois da troca de IP, o usuário é deslogado. Causa: o servidor vincula a sessão rigidamente ao endereço. Solução: não trocar de IP dentro da mesma sessão lógica e, se a troca for necessária, começar uma nova sessão no novo endereço.
Problema: cookies de sessões diferentes se misturam. Causa: um CookieJar compartilhado para vários proxies. Solução: dar a cada sessão lógica um armazenamento separado e nunca compartilhar.
Problema: o bug aparece de vez em quando no trabalho paralelo. Causa: corrida ao gravar em um objeto compartilhado por várias threads. Solução: isolar as sessões por thread usando dados locais da thread ou usar um bloqueio.
Problema: a autenticação funciona, mas cai logo em seguida. Causa: perda de cookie no redirecionamento. Solução: verificar a coleta de cookies em todas as etapas da cadeia de redirecionamentos e ativar o registro do Set-Cookie.
Problema: o estado restaurado não funciona. Causa: cookies vencidos ou de sessão foram salvos, ou domínio e caminho foram informados incorretamente. Solução: salvar apenas cookies permanentes ainda válidos e restaurar com o domínio e o caminho corretos.
Problema: o token CSRF está sempre inválido. Causa: o cookie da sessão à qual o token está vinculado foi perdido. Solução: primeiro restaure a integridade dos cookies da sessão; o token se ajusta automaticamente.
Problema: o JWT para de funcionar depois da rotação. Causa: um serviço específico vinculou o token ao IP do lado dele. Solução: não trocar de IP durante a vida útil do token ou obter um novo token no novo endereço.
Recursos adicionais e otimização
Quando o esquema básico estiver funcionando, você pode turbiná-lo.
Pool de sessões prontas
Em vez de criar uma sessão toda vez, mantenha um pool de sessões lógicas previamente criadas e autenticadas, cada uma com seu proxy. Pegue uma sessão livre, use-a e devolva-a ao pool. Isso agiliza o trabalho, porque a autenticação não é repetida sem necessidade.
Verificação automática de atividade (health check)
Adicione uma função que faz uma requisição leve ao serviço e verifica se a sessão ainda está viva. Se o servidor responder como se você não estivesse autenticado, a sessão é marcada para reautenticação. Assim, você percebe a expiração antes que ela estrague uma operação importante.
Dica: Faça a verificação de atividade não antes de cada requisição, mas em intervalos agendados ou após pausas longas. Verificações frequentes demais geram carga desnecessária e não trazem benefício.
Armazenamento centralizado de estados
Para projetos maiores, em vez de arquivos, use um banco de dados como armazenamento de cookies. A chave é o identificador da sessão lógica; o valor é o estado serializado. Isso é mais fácil de escalar e mais seguro de armazenar.
Métricas e observabilidade
Conte quantas vezes ocorre logout, quantas sessões precisaram ser recriadas e com que frequência a restauração é bem-sucedida. Esses números mostram a saúde do seu sistema e indicam onde algo está mal configurado.
FAQ: perguntas frequentes
É obrigatório criar um novo objeto de sessão a cada troca de IP? Se o serviço verifica o endereço de forma rígida, sim, porque a sessão antiga não será aceita no novo IP de qualquer jeito. Se o serviço tolera, você pode transferir os cookies para um novo contêiner com o novo proxy e continuar.
Posso usar um mesmo proxy para várias sessões lógicas? Do ponto de vista do código, pode, mas cada sessão lógica ainda precisa ter seu próprio armazenamento de cookies. O que pode ser compartilhado são apenas as configurações de conexão, nunca o estado.
Por que não posso simplesmente guardar todos os cookies em um só lugar e filtrar por domínio? Porque o problema não é o domínio, e sim a vinculação a uma sessão lógica e a um IP específicos. Cookies de uma sessão em um domínio não devem ir para outra sessão no mesmo domínio.
Como descobrir se o serviço vincula a sessão ao IP? Faça um experimento: autentique-se em um IP, troque o endereço e faça uma requisição. Se deslogar, provavelmente há vinculação. Volte para o IP antigo: se restaurar, significa que o servidor lembra do primeiro endereço.
O que fazer com cookies de sessão ao salvar no disco? Normalmente não faz sentido salvá-los, porque o servidor os considera inválidos depois que a conexão é interrompida. Salve cookies permanentes com validade em vigor.
E se a biblioteca não salvar os cookies sozinha no redirecionamento? Processe o cabeçalho Set-Cookie manualmente em cada resposta intermediária da cadeia de redirecionamentos e coloque os cookies no seu armazenamento.
Preciso de bloqueio se cada thread tiver sua própria sessão? Não. Se os dados não são compartilhados, não há corrida, e o bloqueio não é necessário. O bloqueio só é preciso quando há acesso compartilhado forçado a um mesmo objeto.
Por quanto tempo posso manter o estado restaurável? Exatamente até o servidor considerar a sessão viva. O prazo exato depende do serviço. É mais prático verificar a atividade com uma requisição do que adivinhar pelo tempo.
O que é mais importante: salvar os cookies ou salvar o token? Depende do mecanismo de autenticação do serviço. Às vezes o token basta; às vezes é preciso o conjunto completo de cookies. O mais seguro é salvar todo o estado de uma vez, assim você não perde o que é necessário.
Posso transferir cookies entre Python e Node.js? Sim, se você salvá-los em um formato neutro comum, como JSON, com campos de nome, valor, domínio, caminho e validade. Assim, qualquer um dos sistemas consegue ler.
Conclusão
Vamos fechar com um resumo do que você percorreu. Você entendeu que, depois da troca de IP, o logout não acontece por causa do simples fato de o endereço mudar, e sim por causa das verificações do servidor e de erros na sua arquitetura. Você aprendeu que cookies, CSRF e JWT, por si só, não estão vinculados ao endereço — a vinculação é adicionada por um serviço específico. Você absorveu a regra principal: uma sessão lógica é igual a um conjunto de cookies e igual a um IP.
Depois, você escreveu um código funcional. No Python, usando um objeto Session separado com seu próprio CookieJar para cada proxy e isolamento por threads. No Node.js, usando a combinação de axios, tough-cookie e o agente de proxy, com um client separado para cada sessão lógica. Você aprendeu a salvar o estado entre execuções, a considerar os prazos de validade dos cookies e a saber quando é mais simples descartar o estado.
Você analisou três erros traiçoeiros: o CookieJar compartilhado, a corrida no trabalho paralelo e a perda de Set-Cookie em redirecionamentos. E agora você tem um checklist antes de colocar em produção, que não deixa você publicar uma solução crua.
O que fazer a seguir
Comece pelo pequeno. Pegue um cenário real, implemente uma sessão lógica isolada para ele e confirme que o estado não se perde. Depois, adicione o salvamento no disco. Depois, escale para várias sessões. Avance um passo de cada vez, verificando o resultado em cada etapa.
Onde evoluir daqui
Depois, vale aprofundar em observabilidade: configurar métricas de atividade das sessões e registro de eventos. Em seguida, aprender a transferir o estado de forma consciente quando o serviço tolera a troca de endereço. E, por fim, montar um pool de sessões prontas para acelerar o trabalho. Cada um desses passos deixa o seu sistema mais robusto e previsível. Você vai conseguir — o princípio você já entendeu, e o resto é questão de prática.