Introdução aos Princípios de Autenticação JWT

Índice- Características da autenticação tradicional

  • Características da autenticação JWT
  • Anatomia do token JWT
  • Fluxo de operação do JWT
  • Considerações de segurança

O JSON Web Token (JWT) é um padrão aberto (RFC 7519) que define uma forma compacta e autocontida para transmitir informações entre partes de forma segura através de objetos JSON. Essas informações podem ser验真 e confiáveis pois são assinadas digitalmente.

O JWT é essencialmente um Token padronizado, desenvolvido para substituir os mecanismos tradicionais de autenticação baseados em Session. A seguir, apresentaremos as limitações dos mecanismos tradicionais de autenticação, além de explicar o que é o JWT, como ele funciona e como substitui a abordagem convencional.

Características da autenticação tradicional

Persistência de estado (Stateful): O servidor precisa armazenar informações de sessão de cada usuário em sua memória ou banco de dados.

Escalabilidade comprometida: Em arquiteturas distribuídas ou de microsserviços, as solicitações dos usuários podem ser balanceadas para diferentes servidores. Isso exige que todos os servidores tenham acesso a um armazenamento de sessões compartilhado (como um cluster Redis), aumentando a complexidade.

Problemas de domínio cruzado: Fazer o Cookie funcionar corretamente em múltiplos domínios diferentes requer configuração adicional.

Características da autenticação JWT

Ausência de estado (Stateless): O servidor não armazena nenhuma informação de sessão do usuário. O estado de login e as informações do usuário são codificados diretamente no próprio token JWT.

Autocontenção (Self-contained): O token em si contém todas as informações necessárias do usuário (como ID, funções, etc.), permitindo que o servidor confie em seu conteúdo apenas verificando a validade do token.

Facilidade em cenários de múltiplos domínios e transmissão: O JWT pode ser enviado no cabeçalho HTTP (Authorization Header), parâmetros POST ou até mesmo na URL. Por ser apenas uma string, pode ser transmitido facilmente entre diferentes domínios e serviços.

O JWT também é um Token, cuja definição é: Token geralmente é uma string que contém informações do usuário e dados criptografados, comumente usada para verificar identidade e permissões. O uso de Token evita a necessidade de autenticação em cada solicitação, melhorando o desempenho de aplicações web e resolvendo o problema de login repetido.

Anatomia do token JWT

O JWT pode ser visto como uma string composta por múltiplas informações JSON concatenadas. Para facilitar a memorização: cabeçalho + corpo + assinatura.

**Estrutura do JWT:**Um JWT aparece como uma string longa separada por pontos (.), exemplo: xxxxx.yyyyy.zzzzz

Ele é composto por três partes, correspondendo aos três pontos separadores:

  1. Header (Cabeçalho)

Função: Descrever informações básicas do token, como tipo (JWT) e algoritmo de assinatura utilizado (como HMAC SHA256 ou RSA).

Conteúdo: Um objeto JSON, por exemplo {"alg": "HS256", "typ": "JWT"}

Armazenamento: Este objeto JSON passa por codificação Base64Url, formando a primeira parte do JWT (xxxxx). 2. Payload (Carga útil)

Função: Transportar as "declarações" (Claims) desejadas. Declarações são informações públicas sobre uma entidade (normalmente o usuário).

Conteúdo: Um objeto JSON contendo três tipos de "declarações":

  • Declarações registradas (Registered claims): Campos padrão predefinidos no JWT, não obrigatórios mas recomendados. Os mais comuns são:
  • iss (issuer): Emitente
  • aud (audience): Destinatário
  • sub (subject): Assunto
  • iat (issued at time): Tempo de emissão do JWT
  • exp (expiration time): Tempo de expiração do JWT
  • ......
  • Declarações públicas (Public Claims) Já registradas em um registro público (como IANA JWT Registry), ou usando nomes que evitam conflitos (como contendo uma URL completa).
  • Declarações privadas (Private Claims) Declarações personalizadas combinadas privativamente. Exemplo: {"nota_do_aluno": "85"}

Armazenamento: Este objeto JSON deve ser codificado em Base64Url, formando a segunda parte do JWT (yyyyy).

⚠️ Aviso importante: Header e Payload são apenas codificados (Base64Url), não criptografados! Qualquer pesssoa pode decodificá-los e ver o conteúdo original. **Por isso, nunca coloque informações sensíveis como senhas no Payload. Este também é um item de verificação de segurança.**3. Signature (Assinatura)

Função: Esta é a parte mais crucial do JWT, usada para prevenir alterações no token e garantir que confiemos em seu conteúdo.

Método de geração: Assinar o Header codificado, o Payload codificado e uma chave secreta (Secret) usando o algoritmo especificado no Header (como HS256).

Pseudocódigo: Signature = HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)

Método de verificação: Ao receber o JWT, o servidor gera novamente uma assinatura usando a mesma chave e algoritmo nas duas primeiras partes. Se a nova assinatura gerada for exatamente igual à terceira parte do JWT, isso prova que o token não foi alterado (pois invasores sem a chave não podem gerar assinaturas válidas). Simultaneamente, isso confirma que o emissor possui a chave (normalmente o servidor que emitiu o token).

Por fim, conectando essas três strings Base64Url com pontos, obtemos um JWT completo. xxxxx.yyyyy.zzzzz

Fluxo de operação do JWT

Este fluxo demonstra como o JWT implementa autenticação stateless, onde o cliente只需携带 token em cada solicitação, e o servidor verifica assinatura e declarações para determinar a legitimidade da solicitação, sem necessidade de um servidor central para manter o estado da sessão do usuário.

  1. Login do usuário: O usuário envia nome de usuário e senha para o servidor de autenticação.
POST /api/login HTTP/1.1
Host: api.exemplo.com
Content-Type: application/json

{
  "usuario": "marcos",
  "senha": "senha123"
}


  1. Verificação de credenciais: O servidor de autenticação verifica se nome de usuário e senha estão corretos.
  2. Geração do JWT: Após validação bem-sucedida, o servidor gera o JWT. Nele:
  • Header especifica o algoritmo.
{
  "alg": "HS256",
  "typ": "JWT"
}
→ Após codificação Base64Url: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9


  • Payload contém informações como ID do usuário, função, tempo de expiração.
{
  "sub": "9876543210",
  "nome": "Marcos",
  "iat": 1619000000,
  "exp": 1619003600
}
→ Após codificação Base64Url: eyJzdWIiOiI5ODc2NTQzMjEwIiwibm9tZSI6Ik1hcmNvcyIsImlhdCI6MTYxOTAwMDAwMCwiZXhwIjoxNjE5MDAzNjAw


  • Signature usa uma chave conhecida apenas pelo servidor (Secret), gerada com base no Header e Payload.
HMACSHA256(
  base64UrlEncode(header) + "." + base64UrlEncode(payload),
  "chave-secreta-256-bits-do-servidor" // Chave do servidor
)
→ Assinatura calculada: XyLpwRxTJSmooPPQz4fwNmeJf46ROy8xLV_dAssw8b


  1. Retorno do JWT: O servidor retorna o JWT gerado ao cliente (geralmente no cabeçalho Authorization ou no corpo da resposta HTTP). eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5ODc2NTQzMjEwIiwibm9tZSI6Ik1hcmNvcyIsImlhdCI6MTYxOTAwMDAwMCwiZXhwIjoxNjE5MDAzNjAw.XyLpwRxTJSmooPPQz4fwNmeJf46ROy8xLV_dAssw8b
  2. Armazenamento no cliente: O cliente (normalmente o navegador) recebe e armazena (comumente em localStorage ou sessionStorage).
  3. Solicitações com JWT: A partir de então, qualquer solicitação a APIs protegidas deve incluir o JWT no cabeçalho HTTP (formato usual: Authorization: Bearer <token>).
  4. Recálculo da assinatura: Verificação do JWT pelo servidor: O servidor de API recebe a solicitação:
  • 7.1 Verificação de assinatura: Recalcula a assinatura usando a mesma chave nas duas primeiras partes do JWT, comparando com a terceira parte para validar autenticidade e ausência de modificações.
  • 7.2 Verificação de validade: Examina o campo exp no Payload para garantir que o token não expirou.
  • 7.3 Verificação do emissor (opcional): Confere se o campo iss é confiável.
  1. Retorno da resposta: Após validação bem-sucedida, o servidor considera a solicitação proveniente de um usuário autenticado e processa a requisição conforme as informações do Payload (como função do usuário), retornando o resultado.

Diagrama de sequência de operação:

Conclusão: O mecanismo tradicional de autenticação exige um servidor central para armazenar e processar o mapeamento de usuários, sendo bastante problemático e com baixa escalabilidade.

Em contrapartida, o JWT é uma implementação típica de autenticação baseada em assinatura (Signature-based Authenticasion), sendo mais eficiente, de implantação mais simples, com maior desacoplamento e adequada para expansão.

Considerações de segurança

Proteção de chave: A chave do servidor deve ser mantida em sigilo e suficientemente complexa;

HTTPS: Toda comunicação deve ocorrer via HTTPS, prevenindo roubo do token;

Tempo de expiração adequado: Configurar tempo de expiração apropriado, equilibrando segurança e experiência do usuário;

Informações sensíveis: Não armazenar dados sensíveis no payload (como senhas);

Gerenciamento de revogação: JWT não pode ser invalidado durante seu período de validade, sendo necessário combinar lista negra ou estratégias de validade curta;

Tags: jwt json-web-token autenticacao Segurança stateless

Publicado em 8-6 17:29