Fala pessoal, tudo bem? Hoje quero conversar com vocês sobre um tema fundamental para quem está trabalhando com aplicações web e deseja conhecer mais sobre autenticação: JSON Web Tokens (JWT). Se você já viu esse termo por aí, mas ainda não entende ao certo como ele funciona por baixo dos panos, este post é para você! Vou explicar de forma didática como os sistemas utilizam JWT para autenticar usuários, por que ele é tão usado em diversos projetos e o que você precisa ter em mente ao trabalhar com essa abordagem.
Caso prefira, assista ao vídeo:
O que é um JSON Web Token
O JSON Web Token é, basicamente, esse conjunto de caracteres “grandões” que a gente vê quando fala de autenticação baseada em tokens. Ele serve para verificar e autenticar que você (ou qualquer usuário) é, de fato, quem diz ser, no momento em que acessa determinado sistema.
Funciona assim: você acessa um site que exige login, informa seu usuário (ou e-mail) e sua senha. Ao validar seus dados, o servidor gera um token – ou seja, uma string codificada que contém algumas informações sobre você – e o envia de volta para que seu navegador (front-end) guarde. É esse token que será enviado em todas as requisições futuras para dizer ao servidor “Ei, sou eu mesmo, me dá acesso aos meus dados!”.
Estrutura de um JWT
Um JWT é composto por três partes principais, normalmente separadas por pontos:
- Header (cabeçalho)
- Payload (corpo ou “dados”)
- Signature (assinatura)
É comum representarmos essas partes em cores diferentes, como no site
jwt.io. Aqui vai um exemplo de token (fictício) que usarei para ilustrar:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MTIzLCJ1c2VybmFtZSI6Im1pY2hhZWwuc2lsdmEiLCJhZG1pbiI6ZmFsc2UsImlhdCI6MTY2MzYzMTg4NX0.fHIzwQz0r7uNFx2rNNN9fL1b0D70ihLlbCHWNfhm65g
Vamos quebrar esse token nas três partes separadas por ponto:
- Header (vermelho)
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
- Payload (lilás)
eyJpZCI6MTIzLCJ1c2VybmFtZSI6Im1pY2hhZWwuc2lsdmEiLCJhZG1pbiI6ZmFsc2UsImlhdCI6MTY2MzYzMTg4NX0
- Signature (azul)
fHIzwQz0r7uNFx2rNNN9fL1b0D70ihLlbCHWNfhm65g
Decodificando o Header
Se você fizer a decodificação (base64URL decode) da primeira parte:
{
"alg": "HS256",
"typ": "JWT"
}
alg: Algoritmo usado para assinar o token (neste caso, HS256).
typ: Tipo do token (JWT).
Decodificando o Payload
A segunda parte, quando decodificada, pode se parecer com isto:
{
"id": 123,
"username": "michael.silva",
"admin": false,
"iat": 1663631885
}
id: ID do usuário.
username: Nome de usuário.
admin: Indica se o usuário é administrador ou não.
iat: Timestamp de quando o token foi emitido (“issued at”).
A Signature (terceira parte)
Já a terceira parte (Signature) é a parte que garante a integridade do token. Não há algo “decodificável” aqui no mesmo sentido do Header e do Payload, pois se trata da assinatura resultante da aplicação de uma função de hash, utilizando uma chave secreta que só o servidor conhece.
Exemplo prático de uso
Imagine este cenário:
- Você tem um servidor de autenticação que valida seu e-mail e senha.
- Ao confirmar que você é realmente você, esse servidor gera um JWT contendo algumas informações úteis, como:
- id do usuário,
- admin (true ou false, indicando se é administrador),
- e outros campos necessários.
- Esse servidor de autenticação retorna o token para o navegador ou app.
- Agora você quer acessar outro sistema, por exemplo, um e-commerce. Esse e-commerce não tem nenhum dado salvo localmente sobre quem você é, apenas confia na informação contida no token. Então, ao receber seu JWT, ele decodifica o Payload, vê seu ID e carrega, por exemplo, todos os pedidos vinculados a esse usuário.
Esse processo pode ocorrer entre diversos serviços. Basta que o serviço que precisa das informações saiba validar a assinatura do token. E como funciona essa validação?
Como funciona a assinatura (Signature)
A Signature é a parte que impede que alguém simplesmente altere os dados no Payload e finja ser outra pessoa. Quando o servidor gera o JWT, ele faz o seguinte:
- Pega o Header codificado em Base64URL.
- Pega o Payload codificado em Base64URL.
- Concatena os dois com um ponto no meio (ex.:
header.payload
). - Passa essa string concatenada + uma chave secreta (que só o servidor conhece) por um algoritmo de hashing (por exemplo, HS256).
- Como resultado, tem uma assinatura (Signature) totalmente única.
Quando você recebe o token, o JWT é algo como:
headerCodificado.payloadCodificado.assinaturaGerada
Na hora de validar, o servidor refaz o processo internamente com a mesma chave secreta que só ele possui. Se, por algum motivo, alguém tiver alterado qualquer informação no Payload ou no Header, a assinatura não vai bater. E, assim, o token é rejeitado.
Por que não consigo simplesmente mudar o “admin” para true?
Se você pegar o Payload no exemplo acima e trocar "admin": false
para "admin": true
, seu token muda. Para que ele seja aceito, você precisaria gerar uma nova assinatura com a mesma chave secreta que o servidor original tem. Como essa chave está segura no servidor, você não conseguiria recriar a assinatura válida. Resultado: o servidor imediatamente identificaria esse token como inválido.
Codificação x Criptografia
Codificação (ou encoding) em Base64URL não é a mesma coisa que criptografia. Codificar é apenas tornar o conteúdo transmissível em formato de texto, mas a pessoa que receber aquele texto consegue decodificá-lo facilmente.
Criptografar é outra história: você normalmente precisa de uma chave para descriptografar. No JWT, a parte que envolve a segurança não é o sigilo do Payload, mas a assinatura. Por isso, o Payload em si não é protegido de quem o lê, mas sim de quem deseja adulterá-lo.
E depois que o usuário está autenticado?
Vamos supor que você fez login, recebeu seu token e agora quer acessar a página de “Meus Pedidos”. O sistema (back-end) vai receber a requisição contendo seu JWT, decodificar, verificar a assinatura e, se estiver tudo certo, identificar seu ID e buscar os pedidos correspondentes no banco de dados. Tudo isso sem precisar verificar senha a cada nova requisição, pois o token já “prova” que você é você.
Próximos passos: Access Token, Refresh Token e mais
Neste post, mostrei de maneira didática como o JWT funciona por baixo dos panos:
- Estrutura de três partes (Header, Payload e Signature).
- Uso de Base64URL para facilitar o tráfego na web.
- Como a assinatura evita adulterações.
- Por que não se deve colocar dados sensíveis no Payload.
Em conteúdos futuros, abordarei mais detalhes sobre Access Token, Refresh Token, estratégias para expiração do token e como gerenciá-los com maior segurança no seu front-end e back-end.
Se tiver sugestões de novos temas ou dúvidas, deixe nos comentários! Espero que este conteúdo tenha ajudado a esclarecer como o JWT funciona na prática e por que ele é tão utilizado em aplicações modernas.
Até a próxima! E não esqueça de se inscrever, compartilhar e continuar acompanhando o blog para mais conteúdos relevantes.
Dica Extra: Se quiser ver uma demonstração interativa, visite
jwt.io e faça testes com o Header, Payload e chave secreta para entender melhor como cada mudança altera a assinatura do token.