Desenvolvimento· Arrumando a casa · parte 12
O antispam esperou tanto que parou o formulário.
Como defini o que bloquear quando o Turnstile falha, o que deixar passar e o que registrar para manter a captura disponível.

O desafio também pode impedir a captura
Quando o Turnstile demorava para responder, o formulário parava de receber e-mails. Em um produto que ainda não apresentei aqui, a captura esperava até 10 s pelo token, mas não havia prazo para o carregamento do próprio script. Se esse carregamento falhasse, a falha ficava guardada pela sessão inteira.
A API tratava o token vazio como uma checagem reprovada. Com challenges.cloudflare.com lento ou bloqueado, a captura parava, embora o requisito do produto determinasse que ela deveria deixar passar nessa situação.
Isso criou uma diferença entre o comportamento desejado e o que o visitante encontrava. A proteção estava na frente do formulário, mas a indisponibilidade do serviço recebia o mesmo tratamento de uma rejeição.
Um prazo cobre o script e o token
A correção colocou um prazo único de 5 s para o carregamento do script e a obtenção do token. Uma falha deixa de ficar presa pela sessão: na chamada seguinte, o processo pode tentar novamente. O widget só aparece quando a Cloudflare pede interação.
No servidor, token vazio passa a significar serviço indisponível. Nesse caso, a API não chama o siteverify e registra no_token no log. A passagem consome uma unidade extra do limite por IP como compensação.
Token presente e rejeitado segue bloqueado, com mensagem própria. Essa distinção deixa explícito o que eu permito quando a proteção não responde e o que continuo recusando quando ela responde com uma rejeição.
Os testes precisam de uma resposta prevista
Em outro produto, a suíte de navegador no CI não tinha chave do site. O fluxo de visitante esperava pelo Turnstile, três fluxos chegaram ao timeout e a suíte bateu em 30 minutos. A solução foi usar as chaves de teste do Turnstile.
O caso mostra que o ambiente de teste precisa contemplar o serviço do qual o fluxo depende. Sem uma resposta prevista para ele, a espera de um componente pode transformar três fluxos em uma suíte parada.
Nesse mesmo produto, o limite por IP também deixa passar se o serviço de contagem falha ou demora 2 s. O erro é registrado, porque login e análise precisam continuar disponíveis.
Cada produto escolhe a proteção que precisa
No Pagenello, o formulário combina Turnstile, limite por IP e proteção contra duplicados. Nos dois sites que são apenas estáticos, não há Turnstile porque não há formulário. A escolha acompanha o fluxo que precisa de proteção.
O token é a resposta que o formulário recebe para levar a verificação ao servidor. Se ele não chega, o servidor precisa saber distinguir essa ausência de uma resposta que chegou e foi recusada. Essa separação define o comportamento do formulário quando a dependência está indisponível.
O prazo único cobre o caminho inteiro até a resposta. Limitar apenas a espera pelo token deixava uma etapa anterior sem limite, de modo que o visitante ainda podia ficar preso antes de chegar à verificação. Ao reunir as duas esperas, a decisão de seguir não depende de descobrir em qual parte o carregamento parou.
A nova tentativa na chamada seguinte também evita transformar uma falha temporária em uma condição permanente da sessão. Se o serviço voltar a responder, o próximo envio pode usar a proteção novamente. Enquanto isso, o registro de no_token deixa uma pista sobre a passagem sem token.
Eu copiaria a decisão como uma pequena tabela de comportamentos: ausência de resposta, resposta rejeitada e resposta aceita. Para cada situação, escreveria o que o visitante vê, se a API continua e qual registro fica disponível. Depois conferiria o fluxo com o serviço lento ou indisponível, além do caminho em que ele responde.
A compensação no limite por IP faz parte da escolha de deixar passar. Ela não transforma a ausência do token em uma verificação bem-sucedida; acrescenta uma restrição ao fluxo que continua. A mensagem própria para uma rejeição mantém esse caso separado para quem usa o formulário. O registro de no_token permite separar depois as passagens sem token das respostas rejeitadas.
Essa lição apareceu em cada produto e ainda não é um padrão escrito entre eles. O critério que uso ao examinar uma falha é definir o que fica barrado, o que pode passar e o que compensa essa passagem. Em publicar da minha máquina, conto outra decisão em que explicitei os riscos aceitos.