Pular para o conteúdo
Aback Tools Logo

Como Validar a Configuração JWT em TypeScript: Algoritmos, Claims e Segredos

Como validar a configuração JWT em TypeScript: forçar algoritmos no jwt.verify(), validar claims exp/nbf/iss/aud, rotacionar chaves com JWKS e depurar tokens com ferramentas no navegador.

DH
Tutorials & How-Tos12 min de leitura2,750 palavras

A maioria dos bugs de JWT em TypeScript não está no token — está na configuração de verificação. Uma restrição de algoritmo ausente, um claim de emissor sem verificação ou um segredo de vida curta podem minar silenciosamente a autenticação de uma forma que só aparece em produção. Este guia percorre todas as dimensões da correção da configuração JWT em TypeScript: algoritmos, validação de claims, higiene de segredos, tratamento de expiração e as ferramentas de navegador que agilizam a depuração.

3Partes do cabeçalho JWTcabeçalho · payload · assinatura
RS256Algoritmo recomendadoAssimétrico, seguro em produção
0 KBEnvios ao servidorDepuração JWT no navegador

O que a validação de configuração JWT cobre

Um JSON Web Token (JWT) é uma string compacta e segura para URL formada por três partes codificadas em Base64URL separadas por pontos: um cabeçalho que declara o algoritmo e o tipo de token, um payload que carrega os claims e uma assinatura que os vincula. Validar um JWT significa confirmar que as três partes estão intactas e que os claims atendem aos requisitos da sua aplicação — não apenas que a assinatura é matematicamente correta.

As duas camadas da validação JWT

A validação criptográfica confirma a assinatura: o servidor verifica que o token foi assinado com a chave esperada e não foi adulterado. A validação de configuração vai além: verifica que o token foi emitido pela autoridade certa, destina-se a este serviço específico, não expirou e carrega os claims personalizados esperados. A maioria das vulnerabilidades de segurança JWT vem de validação de configuração incompleta, não de criptografia quebrada.

  • Algoritmo (`alg`) - deve corresponder exatamente à configuração do seu servidor; nunca o infira do cabeçalho do token
  • Expiração (`exp`) - o token não deve ter passado do carimbo de data/hora de expiração, considerando a tolerância de relógio
  • Não-antes-de (`nbf`) - o token não deve ser usado antes do seu primeiro horário válido
  • Emissor (`iss`) - o token deve se originar do seu serviço de autenticação confiável
  • Audiência (`aud`) - o token deve se destinar a esta API ou serviço específico
  • Claims personalizados - papel, escopo, ID de tenant ou qualquer campo específico da aplicação do qual sua lógica dependa

Note

A validação da estrutura JWT (verificar que o token é uma string Base64URL válida de três partes) é um pré-requisito de todas as demais validações. O [Decodificador e Validador JWT](/tools/data/validators/jwt-decoder-and-validator) faz isso instantaneamente no seu navegador - útil para confirmar que um token está bem formado antes de escrever o código de verificação.

Checagens de algoritmo e configuração de chaves

A configuração do algoritmo é a definição mais crítica de segurança na verificação JWT. Errar nisso habilita uma classe de ataques que contorna completamente a autenticação. As bibliotecas JWT de TypeScript dão as ferramentas para aplicá-lo corretamente - mas só se você as usar explicitamente.

HS256 vs RS256 - escolhendo o algoritmo certo

PropriedadeHS256 (simétrico)RS256 (assimétrico)
Tipo de chaveSegredo compartilhado (mesma chave para assinar + verificar)Par de chaves RSA (privada para assinar, pública para verificar)
Distribuição de chavesTodo verificador detém o segredoApenas o emissor detém a chave privada
Segurança multi-serviço✗ Arriscado - todos os verificadores podem forjar tokens✓ Verificadores detêm apenas a chave pública
Suporte a OIDC / JWKS✗ Não aplicável✓ Chaves públicas servidas via endpoint JWKS
Desempenho✓ Rápido (HMAC)✗ Mais lento (matemática RSA)
Melhor paraFerramentas internas, APIs de serviço únicoAPIs de produção, sistemas distribuídos, OIDC

O ataque de confusão de algoritmo - e como preveni-lo

A confusão de algoritmo acontece quando um servidor lê o campo `alg` do cabeçalho JWT para decidir como verificar o token, em vez de forçar o algoritmo a partir da sua própria configuração. Um atacante modifica o cabeçalho para trocar `RS256` por `HS256`, e então assina o token com a chave pública do servidor usada como segredo HMAC. Um servidor mal configurado o aceita como válido. A correção é uma única linha de código - mas precisa estar presente.

typescript
// ✗ Vulnerable - algorithm inferred from token header
jwt.verify(token, publicKey);

// ✓ Correct - algorithm enforced from server configuration
jwt.verify(token, publicKey, { algorithms: ['RS256'] });

Warning

Nunca omita a opção `algorithms` no `jwt.verify()`. Mesmo que sua versão atual da biblioteca rejeite por padrão o algoritmo `none`, listar explicitamente os algoritmos permitidos no seu código torna a intenção clara, sobrevive a atualizações da biblioteca e elimina por completo a classe de vulnerabilidade de confusão de algoritmo.

Validação da força da chave para HS256

Ao usar HS256, o segredo deve ter pelo menos 256 bits (32 bytes) para corresponder ao tamanho de saída do SHA-256. Segredos curtos - menos de 32 caracteres, palavras de dicionário ou strings estáticas como `"secret"` ou `"development"` - são quebrados trivialmente por força bruta com ferramentas como `hashcat` ou `jwt_tool`. Gere segredos com uma fonte aleatória criptograficamente segura: `crypto.randomBytes(32).toString('hex')` no Node.js produz uma string hexadecimal de 64 caracteres que atende ao requisito mínimo de entropia.

Validar claims JWT padrão em TypeScript

A especificação JWT define um conjunto de claims registrados padrão que toda implementação deveria entender. A biblioteca `jsonwebtoken` valida vários deles automaticamente quando você passa as opções certas - mas a palavra-chave é "quando você as passa". Sem configuração explícita, a maioria das checagens de claims é silenciosamente pulada.

Os claims exp, nbf e iat

O claim exp (expiração) é um carimbo de data/hora Unix após o qual o token deixa de ser válido. A biblioteca jsonwebtoken verifica exp por padrão durante jwt.verify(). Porém, o desvio de relógio entre o emissor do token e o verificador pode fazer tokens válidos serem rejeitados - fonte comum de erros de "token expirado" em sistemas distribuídos onde os relógios dos servidores derivam por segundos. Passe clockTolerance para permitir uma janela pequena: definir clockTolerance como 30 aceita tokens até 30 segundos após o valor exp.

typescript
interface JwtPayload {
  sub: string;
  iss: string;
  aud: string;
  exp: number;
  iat: number;
  role: 'admin' | 'user';
}

const payload = jwt.verify(token, publicKey, {
  algorithms: ['RS256'],
  issuer: 'https://auth.example.com',
  audience: 'api.example.com',
  clockTolerance: 30,           // seconds of clock skew to tolerate
}) as JwtPayload;

Os claims iss e aud

O claim `iss` (emissor) identifica a origem do token. O claim `aud` (audiência) identifica o destinatário pretendido. Ambos são opcionais na especificação JWT, mas críticos na prática. Sem validação de `iss`, qualquer serviço que possa produzir tokens válidos com sua chave de assinatura pode autenticar-se na sua API. Sem validação de `aud`, um token emitido para seu app móvel pode ser reutilizado contra sua API administrativa. Passe ambos como opções no `jwt.verify()` para que a biblioteca os imponha como requisitos rígidos em vez de campos informativos.

Tip

Verifique os valores `iss` e `aud` de um token recebido colando-o no [Decodificador e Validador JWT](/tools/data/validators/jwt-decoder-and-validator). O payload decodificado mostra cada claim em formato legível, facilitando confirmar que suas strings de emissor e audiência correspondem ao que a biblioteca está configurada para esperar.

Implementar validação JWT em TypeScript

Uma função completa de verificação JWT em TypeScript lida com validação criptográfica, validação de claims e classificação de erros em um só lugar. Veja como estruturá-la - com os quatro passos que correspondem ao esquema HowTo.

1

Verifique que o algoritmo corresponde ao seu tipo de chave

Antes de escrever qualquer código de verificação, confirme sua combinação de algoritmo e chave. RS256 exige uma chave privada RSA para assinar e a chave pública correspondente para verificar. HS256 exige o mesmo segredo compartilhado dos dois lados. Confundi-los causa exceções em tempo de execução difíceis de diagnosticar. Guarde sua chave pública ou segredo compartilhado em variáveis de ambiente - nunca os escreva em arquivos-fonte.

2

Valide explicitamente os claims exp e nbf

Sempre defina `clockTolerance` para lidar com pequenas derivações de relógio entre serviços. Um valor de 30 segundos é um padrão razoável para a maioria dos sistemas distribuídos. Ao depurar `TokenExpiredError` em produção, registre `payload.exp * 1000` e `Date.now()` juntos - isso mostra exatamente quantos milissegundos o token passou da expiração, distinguindo expiração real de um problema de sincronização de relógios entre seu serviço de autenticação e o servidor da API.

3

Verifique os claims iss e aud contra os valores esperados

Passe as opções `issuer` e `audience` ao `jwt.verify()` para que a biblioteca rejeite tokens com valores divergentes antes que seu código de aplicação rode. Se seu sistema tem múltiplas audiências válidas (por exemplo, tanto `api.example.com` quanto `admin.example.com`), passe um array: `audience: ['api.example.com', 'admin.example.com']`. A biblioteca aceita o token se o claim `aud` corresponder a qualquer entrada do array.

4

Teste sua configuração com o Decodificador JWT

Antes de rodar sua suíte de testes TypeScript, cole um token de exemplo do seu ambiente de desenvolvimento ou staging no Decodificador e Validador JWT. Confirme visualmente que cada claim - `alg`, `exp`, `iss`, `aud` e seus claims personalizados - corresponde às opções do seu `jwt.verify()`. Essa checagem de um minuto captura divergências entre o que o token contém e o que seu código espera, antes de gastar tempo depurando em um ambiente de teste.

Decodificador e Validador JWT

Decodifique tokens JWT e inspecione todos os claims, campos do cabeçalho e problemas de segurança comuns instantaneamente no seu navegador - sem cadastro, sem envio ao servidor.

Open tool

Erros comuns de configuração JWT

Estes são os erros de configuração que aparecem com mais frequência em implementações JWT em TypeScript. Cada um é silencioso na inicialização e só se manifesta como uma falha de autenticação ou incidente de segurança em produção.

Usar `jwt.decode()` em vez de `jwt.verify()`

A função `jwt.decode()` extrai o payload sem verificar a assinatura. É útil para inspecionar um token em que você já confia - como extrair um ID de usuário de um token já validado pelo middleware. Não é um substituto do `jwt.verify()`. Código que usa `jwt.decode()` para obter claims e depois toma decisões de autorização com base nesses claims está aceitando tokens não verificados. Isso é um bypass completo da autenticação.

Ignorar o tipo de erro nos blocos catch

A biblioteca `jsonwebtoken` lança três tipos de erro distintos: `JsonWebTokenError` (token malformado ou assinatura inválida), `TokenExpiredError` (além do claim `exp`) e `NotBeforeError` (antes do claim `nbf`). Capturar todos os erros como um `Error` genérico e retornar `401 Unauthorized` para todos os casos perde informação de diagnóstico. Trate cada tipo separadamente e retorne mensagens específicas - `token expirado` versus `token inválido` - para que clientes e sistemas de monitoramento distingam problemas de configuração de tentativas de ataque reais.

Não rotacionar segredos ou pares de chaves

Segredos de assinatura de vida longa acumulam risco com o tempo. Um segredo que nunca foi rotacionado significa que todo token já emitido com ele permanece válido se o segredo for comprometido. Implemente um campo de ID de chave (`kid`) no seu cabeçalho JWT para que o verificador possa buscar a chave pública correta em um endpoint JWKS. Esse padrão permite rotação de chaves sem invalidar tokens assinados pela chave anterior - cada token carrega uma referência à chave específica que o assinou. O Inspetor de JWK ajuda a validar a saída do endpoint JWKS e detectar material de chave privada que não deveria estar exposto publicamente.

Warning

Nunca commeta segredos JWT ou chaves privadas ao controle de versão. Use variáveis de ambiente para todo o material de chave, carregue-os em tempo de execução e confirme que estão definidos antes de aceitar qualquer requisição. Uma aplicação que inicia com segredo indefinido ou vazio aceitará silenciosamente tokens assinados com uma string vazia.

Aceitar o algoritmo `none`

O algoritmo `none` produz um JWT não assinado - qualquer payload com estrutura válida passa na verificação. Versões antigas das bibliotecas JWT aceitavam `none` por padrão. Bibliotecas modernas o rejeitam, mas apenas quando você especifica explicitamente os algoritmos permitidos nas opções de verificação. Inclua sempre `algorithms: ['RS256']` (ou seu algoritmo específico) para tornar a rejeição de `none` explícita e resiliente a mudanças de versão da biblioteca.

Depurar problemas de JWT com ferramentas no navegador

Escrever um teste para reproduzir um erro de JWT costuma ser mais lento do que inspecionar o token diretamente. Ferramentas de navegador permitem examinar os claims, o estado de expiração e a estrutura de chaves de um token em segundos - sem ambiente local, sem executar código e sem enviar dados sensíveis a um serviço de terceiros.

Decodificar e inspecionar claims

O Decodificador e Validador JWT decodifica o cabeçalho e o payload de qualquer string JWT e apresenta todos os claims em formato estruturado e legível. Ele verifica problemas de segurança comuns - `exp` ausente, algoritmo fraco, `aud` ausente - e os sinaliza com diagnósticos claros. Cole qualquer token do seu ambiente de desenvolvimento, staging ou produção e confirme em dez segundos se os claims correspondem ao que sua chamada `jwt.verify()` espera.

Diagnosticar problemas de expiração

A Calculadora de Contagem Regressiva de Expiração JWT lê o claim `exp` de qualquer token e mostra o tempo de vida restante exato ou o tempo desde a expiração tanto em UTC quanto no horário local. Quando um usuário relata "token expirado" mas seus logs mostram que o token ainda deveria ser válido, cole-o na calculadora. A comparação de carimbos de data/hora em nível de milissegundo revela se o problema é expiração genuína, desvio de relógio entre serviços ou um valor `exp` armazenado em milissegundos em vez de segundos - um bug de fator 1000 surpreendentemente comum.

Inspecionar conjuntos de chaves JWKS

Ao validar tokens de um provedor OIDC ou de qualquer serviço que publique um endpoint JWKS, o Inspetor de JWK analisa e valida a estrutura do conjunto de chaves. Ele verifica que cada chave tem os campos obrigatórios (`kty`, `use`, `alg`, `kid`), valida o tipo de chave e a curva para chaves EC, e sinaliza qualquer material de chave privada que não deveria estar exposto publicamente. Cole o JSON do seu endpoint JWKS diretamente na ferramenta ou informe a URL para um fetch.

Calculadora de Contagem Regressiva de Expiração JWT

Calcule a contagem regressiva exata de expiração JWT a partir do claim exp - veja o tempo restante ou o tempo desde a expiração em UTC e horário local, sem código.

Open tool

Boas práticas de validação JWT

Uma função de verificação JWT corretamente configurada é necessária, mas não suficiente para autenticação segura. Essas práticas completam o quadro para serviços TypeScript de produção.

Use uma interface de payload tipada

Defina uma interface TypeScript para seu payload JWT e faça cast do resultado da verificação para ela. Isso dá segurança em tempo de compilação quanto aos nomes de claims e tipos de valores - um nome de claim mal escrito (`userId` vs `user_id`) vira um erro de TypeScript em vez de um `undefined` silencioso em tempo de execução. Mantenha a interface em um módulo de tipos compartilhado para que seja consistente em todos os serviços que verificam o mesmo formato de token.

Vidas curtas de token com refresh tokens

Tokens de acesso devem ter vidas curtas - 15 minutos a 1 hora para a maioria das APIs. Tokens de acesso de vida longa (dias, semanas) aumentam a janela durante a qual um token comprometido pode ser usado. Use um fluxo separado de refresh token com expiração longa para persistência de sessão. O refresh token rotaciona a cada uso, e listas de revogação só são necessárias para refresh tokens - não para tokens de acesso - quando as vidas são mantidas curtas.

Centralize a lógica de verificação

Escreva a verificação JWT em um só lugar - uma função de middleware ou uma utilidade compartilhada - e use-a em todos os lugares. Lógica de verificação duplicada convida à deriva de configuração: um endpoint checa `aud`, outro esquece, e a inconsistência é explorada antes que alguém perceba. Middleware do Express, guards do NestJS e handlers de rota do Next.js têm padrões limpos para centralizar checagens de autenticação. Coloque suas opções `algorithms`, `issuer` e `audience` em um único objeto de configuração importado por todo o codebase.

Configure a verificação uma vez, imponha-a em todos os lugares. A única opção JWT que deve diferir entre endpoints é a audiência esperada.

- Princípio de implementação segura de JWT

Tip

Ao adotar um novo provedor de autenticação ou atualizar sua biblioteca JWT, use o [Decodificador e Validador JWT](/tools/data/validators/jwt-decoder-and-validator) para inspecionar tokens da nova fonte antes de atualizar sua configuração de verificação. Isso confirma os valores exatos de `alg`, `iss` e `aud` nos novos tokens para que suas mudanças de código correspondam à realidade - não a suposições.

Key takeaways

  • Passe sempre `algorithms: ['RS256']` (ou seu algoritmo específico) explicitamente ao `jwt.verify()` - nunca deixe a biblioteca inferi-lo do cabeçalho do token.
  • Valide os claims `iss` e `aud` em toda chamada de verificação; omiti-los permite que tokens de outros serviços autentiquem-se contra sua API.
  • Use `clockTolerance` para lidar com desvio de relógio entre serviços distribuídos, e registre carimbos `exp` junto com `Date.now()` ao depurar erros de expiração.
  • Nunca use `jwt.decode()` para decisões de autorização - ele pula completamente a verificação de assinatura e aceita qualquer payload de token.
  • O Decodificador e Validador JWT permite inspecionar todos os claims e sinalizar problemas de configuração em segundos, sem escrever ou rodar código.
  • RS256 é preferível ao HS256 para APIs de produção - elimina o risco de distribuição de segredo compartilhado e suporta rotação de chaves baseada em JWKS.
  • Mantenha vidas curtas dos tokens de acesso (15-60 minutos) e centralize toda a lógica de verificação em um único middleware ou utilidade para prevenir deriva de configuração.

Perguntas frequentes

Use the `jsonwebtoken` library (or `jose` for a modern alternative) and call `jwt.verify(token, secret, { algorithms: ['RS256'], issuer: 'your-issuer', audience: 'your-audience' })`. Always specify the `algorithms` array explicitly - never allow the library to infer it from the token header, as this enables algorithm confusion attacks. Wrap the call in a try/catch and handle `JsonWebTokenError`, `TokenExpiredError`, and `NotBeforeError` separately so you can return informative error responses to API clients.

An algorithm confusion attack occurs when a server accepts the `alg` field from the JWT header to determine how to verify the signature, rather than enforcing the algorithm from its own configuration. An attacker can change `alg` from `RS256` to `HS256` in the header, sign the token with the server's public key as the HMAC secret, and the server will incorrectly validate it as legitimate. The fix: always pass `algorithms: ['RS256']` (or your specific algorithm) explicitly in the verify options.

Call `jwt.verify()` - it throws a `TokenExpiredError` if the `exp` claim is in the past. To inspect expiry without throwing, decode the payload with `jwt.decode(token)` and compare `payload.exp * 1000` to `Date.now()`. For a visual expiry check without writing code, paste your token into the Aback Tools JWT Expiry Countdown Calculator, which shows the exact remaining time or time since expiry in both UTC and local time.

Yes - both are critical. The `iss` (issuer) claim identifies who created the token. Without verifying it, your application will accept tokens issued by any service, including attackers. The `aud` (audience) claim identifies the intended recipient. Without verifying it, a token issued for one of your services can be replayed against another. Pass both as options: `{ issuer: 'https://auth.example.com', audience: 'api.example.com' }`.

HS256 (HMAC-SHA256) uses a single shared secret for both signing and verification. It is simpler to implement but requires every service that verifies tokens to hold the same secret - a security risk in distributed systems. RS256 (RSA-SHA256) uses a private key to sign and a public key to verify. Only the issuing service holds the private key; all consuming services use the public key. RS256 is the recommended algorithm for production APIs where tokens are verified by multiple services or third parties.

After `jwt.verify()` succeeds, cast the result to a typed interface and assert your custom claim values. For example: `const payload = jwt.verify(token, secret) as MyPayload; if (payload.role !== 'admin') throw new Error('Insufficient role')`. Using a TypeScript interface for your JWT payload type gives you compile-time safety on claim names and value types. Validate any claim whose absence or wrong value would represent a security failure - not just standard claims.

The `jose` library is a modern, standards-compliant implementation of JWT, JWS, JWE, JWK, and JWKS that works in Node.js, browsers, Deno, and edge runtimes like Cloudflare Workers. Use `jose` when you need JWKS endpoint support for OIDC, when building for edge or serverless environments, or when you need JWE (encrypted JWT) support. Use `jsonwebtoken` for simple HS256 or RS256 signing and verification in traditional Node.js backends where a shared-secret or static key is sufficient.

Paste the JWT into the Aback Tools JWT Decoder and Validator at abacktools.com/tools/data/validators/jwt-decoder-and-validator. It decodes the header and payload, shows all claims in a readable format, checks for common configuration issues, and flags security problems - all in your browser with no server upload. For expiry checks, the JWT Expiry Countdown Calculator shows exactly how much time remains or how long ago the token expired.

ShareXLinkedIn