Gerador OAuth State
Gera tokens state aleatórios seguros (128 bits) para proteção CSRF em fluxos OAuth 2.0. Recomendado pela RFC 6749.
—
State OAuth assinado: codificando intenção dentro do parâmetro
Existem duas escolas para o parâmetro state do OAuth 2.0. A abordagem aleatória opaca gera uma string de alta entropia, armazena no servidor e compara no callback. A abordagem signed claims embute dados estruturados — nonce anti-CSRF, URL de retorno, intenção do usuário, variante A/B — dentro do próprio state e prova integridade com um HMAC. Ambas previnem CSRF; o state assinado adicionalmente permite que o callback reconstrua contexto sem armazenamento de sessão, o que é decisivo para runtimes serverless e edge (Cloudflare Workers, Vercel Edge, AWS Lambda) onde sessões sticky são caras ou impossíveis.
Um layout típico de state assinado codifica um payload JSON e anexa uma tag HMAC-SHA256, separados por um ponto:
payload = base64url(JSON.stringify({
csrf: random(16), // nonce anti-CSRF
return_url: "/dashboard",
intent: "signup", // signup | login | link
variant: "B", // braço do A/B test
iat: 1716902400, // issued-at (unix)
ttl: 600 // 10 minutos
}))
tag = base64url(HMAC_SHA256(STATE_SECRET, payload))
state = payload + "." + tag
Fluxo de validação no callback
Faça split pelo ponto, recompute o HMAC sobre o payload e compare em tempo constante (crypto.timingSafeEqual). Só depois da tag bater, faça parse do JSON. Em seguida cheque iat + ttl > agora para impor janela de 5-10 minutos — curta o bastante para derrotar replay, longa o bastante para usuários legítimos em rede instável. Rejeite tudo mais velho. Por fim, valide return_url contra uma allowlist de caminhos do mesmo origin para evitar open redirect.
JWT vs HMAC custom
Você pode usar um JWT (jsonwebtoken, jose) para o mesmo papel — as claims exp/iat e assinatura HS256 mapeiam direto em state assinado. JWT é overkill para um valor que vive 10 minutos: o header adiciona bytes e os footguns de algorithm confusion ("alg":"none") são reais. HMAC custom mantém o state mais curto para o orçamento de URL e evita parsers surpresa. libsodium / tweetnacl oferecem crypto_auth se quiser HMAC fora da stdlib.
Higiene e rotação de segredo
Escolha um segredo de 256 bits (32 bytes aleatórios), guarde na variável de ambiente STATE_SECRET, nunca commit no git. Faça rotação mantendo um pequeno keyring — segredo atual e anterior — verificando contra qualquer chave ativa dentro da janela de TTL. Após rotacionar, a chave antiga pode ser aposentada em 10 minutos já que nenhum state em voo sobrevive ao TTL. OAuth 2.1 ainda recomenda state ao lado do PKCE (agora obrigatório); defendem camadas diferentes.
FAQ
Prefiro state assinado a store no servidor? Sim se você é stateless (serverless, edge). Não se já mantém session store — state aleatório é mais simples e fica opaco.
HMAC-SHA256 é forte o bastante? Sim — com segredo de 256 bits é a mesma primitiva por trás de HS256 JWTs, AWS request signing e TLS PRFs. O elo fraco é a disciplina de rotação, não o algoritmo.
Qual TTL ideal? 5-10 minutos para fluxos interativos. Janelas maiores vazam por redirects e shoulder-surfing; menores derrubam usuários reais em rede ruim.
State assinado dispensa PKCE? Não. PKCE liga o authorization code ao cliente original; state assinado defende a URL de callback contra CSRF. Mitigam ataques diferentes e OAuth 2.1 exige ambos para clientes públicos.
Ferramentas Relacionadas
Gerador de Manuscrito
Converte texto digitado em uma imagem com aparência de letra manuscrita. Útil para tornar trabalhos digitais mais pessoais.
Gerador de Currículo
Preenche um currículo simples (CV) imprimível em A4 a partir de formulário com dados pessoais, formação e experiência.
Gerador de Favicon
Gera favicon a partir de texto/emoji em todos os tamanhos comuns (16, 32, 48, 64, 192, 512). Download como PNG.