JWT: Mitos e Verdades – Esclarecimentos e Boas Práticas de Autenticação

JWT: Mitos e Verdades – Esclarecimentos e Boas Práticas de Autenticação





Mitos e Verdades sobre JWT



1. O que é JWT e como funciona

JWT é um token compacto e seguro que transmite informações entre partes, assinado para garantir integridade. Composto por três partes: header, payload e assinatura, ele pode ser assinado (JWS) e, opcionalmente, criptografado (JWE). Em sua forma mais comum, o JWT é apenas assinado, o que permite verificar a autenticidade das claims sem revelar o conteúdo do payload.

  • Header: especifica o algoritmo de assinatura (por exemplo, HS256, RS256) e o tipo (JWT).
  • Payload: conjunto de claims (iss, aud, exp, sub, scopes, etc.). Não é criptografado por padrão; pode ser lido se o token for interceptado.
  • Assinatura: protege a integridade do token e a autenticidade da fonte, usando uma chave compartilhada (HMAC) ou uma chave pública/privada (RSA/EC).

Uso típico: o cliente obtém um JWT após autenticação e o envia em chamadas subsequentes via header Authorization: Bearer token. Em aplicações web, escolha entre armazená-lo em cookies HttpOnly ou guardá-lo com atenção no cliente, conforme o risco de XSS e CSRF.

2. Mitos comuns sobre JWT

  • Mito: JWT substitui sessões. Realidade: JWT é um token tratável como mecanismo de autenticação, mas pode funcionar como substituto de sessão apenas se houver controle de revogação e renovação de tokens.
  • Mito: JWTs sempre protegem dados sensíveis porque são criptografados. Realidade: JWTs são, por padrão, assinados. O payload pode ser lido por qualquer um que tenha o token. Use encryption (JWE) apenas quando necessário.
  • Mito: Armazenar JWTs em localStorage é seguro. Realidade: LocalStorage é vulnerável a XSS. Para aplicações web, cookies HttpOnly com SameSite costumam reduzir riscos; ainda assim, valide tokens com cuidado no servidor.
  • Mito: O payload pode conter qualquer dado sensível. Realidade: Evite dados confidenciais no payload; inclua apenas claims mínimas e identificadores; dados sensíveis devem ficar no backend e não no token.
  • Mito: Revogação de token é simples. Realidade: JWTs são essencialmente stateless. A revogação exige estratégias adicionais (blacklists, rotacionamento de chaves, ou TTL curtos com refresh tokens).

3. Verdades e práticas recomendadas

  • Utilize TLS (HTTPS) para transmissão de tokens em todas as fases do fluxo de autenticação e autorização.
  • Prefira tokens com assinatura (JWS) em vez de criptografia por padrão; se houver necessidade de confidencialidade, utilize JWE.
  • Defina uma expiração curta (expiresIn) e utilize refresh tokens com rotation para evitar janelas de ataque prolongadas.
  • Valide ativamente claims no servidor: iss (emissor), aud (destinatário), exp (expiração) e iat (emissão). Considere uma margem de clock (leeway) para diferenças de tempo.
  • Escolha algoritmos fortes (RS256, ES256 ou EdDSA) e, quando possível, use chaves públicas/privadas; implemente JWKS para rotação de chaves.
  • Evite armazenar dados sensíveis no payload. Mantenha apenas identificadores (sub), escopos (scope), e informações mínimas de autorização, mantendo regras de negócio no backend.
  • Decida entre cookies HttpOnly/SameSite ou armazenamento no cliente com base no seu cenário (SPA, mobile, server-side rendering). Proteja contra CSRF quando usar cookies.
  • Implemente estratégias de revogação ou curto TTL com rotação de tokens para cancelar tokens comprometidos rapidamente.
// Exemplo: verificação de JWT no backend (Node.js com jsonwebtoken)

const jwt = require('jsonwebtoken');

function validarToken(req) {
  const authHeader = req.headers.authorization || '';
  const parts = authHeader.split(' ');
  if (parts.length !== 2 || parts[0] !== 'Bearer') {
    throw new Error('Token inválido');
  }
  const token = parts[1];

  const opts = {
    algorithms: ['RS256', 'RS384', 'RS512'], // ou ['HS256'] se usar segredo compartilhado
    issuer: 'https://your-auth-server.example',
    audience: 'https://your-api.example',
  };

  // Se usar chave pública (RSA/EC):
  const publicKey = getJWKSetPublicKey(); // função que obtém a chave pública correspondente
  const payload = jwt.verify(token, publicKey, opts);

  // Usar payload.sub, payload.scopes etc. para autorização
  return payload;
}

// Exemplo de criação de token (para contexto)
function criarToken(user) {
  const secret = process.env.JWT_SECRET; // para HS256
  const token = jwt.sign(
    { sub: user.id, scope: user.role },
    secret,
    { algorithm: 'HS256', expiresIn: '15m', issuer: 'https://your-auth-server.example', audience: 'https://your-api.example' }
  );
  return token;
}

4. Boas práticas de implementação e cenários de uso

  • Escolha o fluxo de autenticação apropriado: JWT com refresh tokens para clientes móveis e SPAs que precisam manter acesso sem re-login frequente.
  • Defina políticas de rotacionamento de chaves (key rotation) para minimizar impacto de-Key compromise, com JWKS publicados publicamente pelo servidor de autenticação.
  • Considere arquitetura de microserviços: valide tokens em cada serviço, usando audience (aud) e issuer (iss) consistentes para evitar uso indevido entre serviços.
  • Para apps web, avalie o uso de cookies HttpOnly com SameSite=strict ou Lax para reduzir risco de XSS e CSRF, mantendo a compatibilidade com o fluxo de autenticação.
  • Monitore abusos: keys rotacionadas, tentativas de falsificação, e padrões anômalos de uso. Implemente logs de validação de token para auditoria.

Gostou do conteúdo?

Explore mais artigos técnicos sobre autenticação, segurança de APIs e padrões modernos de autorização para aprofundar seu conhecimento.