O que é JSON Web Token (JWT)?
Obtenha uma compreensão clara dos fundamentos do JSON Web Token (JWT) em 5 minutos.
JSON Web Token (JWT) é amplamente utilizado em aplicações web modernas e padrões abertos como o OpenID Connect, facilitando a autenticação e autorização. Embora o oficial RFC 7519 sirva como referência essencial, será um desafio para os iniciantes entender. Neste artigo, focaremos nos conceitos centrais do JWT e os apresentaremos em linguagem simples com exemplos.
Por que precisamos do JWT?
Hoje em dia, é bastante comum usar JSON para trocar dados entre duas partes. Considere um objeto JSON que representa um usuário:
sub
é uma abreviação de "subject", que é um standard claim no OpenID Connect para representar o identificador do usuário (ID do usuário).
Como podemos garantir a integridade deste objeto JSON? Em outras palavras, como podemos ter certeza de que os dados não foram alterados durante a transmissão? Uma solução comum é usar assinaturas digitais. Por exemplo, podemos usar criptografia de chave pública: o servidor assina o objeto JSON com sua chave privada e o cliente pode verificar a assinatura com a chave pública do servidor.
Em resumo, o JWT oferece uma abordagem padronizada para representar o objeto JSON e sua assinatura.
O formato do JWT
Como existem muitos algoritmos para criar assinaturas digitais, é necessário especificar o algoritmo usado para a assinatura do JWT. Isso é realizado construindo um objeto JSON:
alg
é uma abreviação de "algoritmo", etyp
é abreviação de "type".
Normalmente, typ
é definido como JWT
em maiúsculas. Para o nosso exemplo, alg
é HS256
, que representa HMAC-SHA256, e indica que estamos usando este algoritmo para criar a assinatura.
Agora, temos todos os ingredientes para um JWT:
- Header JSON: Algoritmo e tipo
- Payload JSON: Os dados reais
- Assinatura: A assinatura que abrange o header e o payload
No entanto, certos caracteres como espaços e quebras de linha não são amigáveis para a transmissão de rede. Portanto, o cabeçalho e o payload precisam ser codificados em Base64URL. O JWT típico se parece com isto:
O
.
serve como o delimitador.
Vamos juntar tudo e criar um JWT:
Header
JSON: {"alg":"HS256","typ":"JWT"}
Codificado em Base64URL: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Payload
JSON: {"sub":"foo","name":"John Doe"}
Codificado em Base64URL encoded: eyJzdWIiOiJmb28iLCJuYW1lIjoiSm9obiBEb2UifQ
Assinatura
Em HMAC-SHA256, a assinatura é criada com um segredo:
Por exemplo, com o segredo como some-great-secret
, a assinatura se torna: XM-XSs2Lmp76IcTQ7tVdFcZzN4W_WcoKMNANp925Q9g
.
JWT
O JWT final é:
Este JWT válido pode ser verificado por qualquer parte que possua o segredo.
Escolha o algoritmo de assinatura
Como mencionado anteriormente, existem vários algoritmos para criar assinaturas digitais. Usamos HS256
como exemplo, mas ele pode não ser suficientemente forte, pois o segredo deve ser compartilhado entre as partes (por exemplo, o cliente e o servidor).
Em cenários do mundo real, os clientes podem incluir aplicações públicas como aplicativos React que não podem manter o segredo seguro. Consequentemente, a abordagem preferida envolve a utilização de criptografia de chave pública (ou seja, criptografia assimétrica) para assinar o JWT. Vamos começar com o algoritmo mais popular: RSA.
RSA
RSA, um algoritmo assimétrico, usa um par de chaves: uma chave pública e uma chave privada. A chave pública é usada para verificar a assinatura, enquanto a chave privada é usada para assinar.
O header JSON para RSA se parece com isto:
RS256
representa RSA-SHA256, o que significa que a assinatura é criada com o algoritmo RSA e a função de hash SHA256. Você também pode usarRS384
eRS512
para criar assinaturas com funções de hash SHA384 e SHA512, respectivamente.
A assinatura é criada com a chave privada:
Novamente, podemos montar essas partes para criar um JWT, e o JWT final se parece com isto:
Agora, o cliente pode verificar a assinatura sem conhecer a chave privada.
ECDSA
Embora o RSA seja amplamente adotado, ele sofre com tamanhos de assinatura maiores, às vezes superando o tamanho combinado do cabeçalho e payload. O Algoritmo de Assinatura Digital de Curva Elíptica (ECDSA) é outro algoritmo assimétrico que pode criar assinaturas mais compactas e é mais eficiente.
Para gerar uma chave privada para ECDSA, precisamos escolher uma curva. Isso está fora do escopo deste artigo, mas você pode encontrar mais informações aqui.
O header JSON para ECDSA se parece com isso:
ES256
representa ECDSA-SHA256, o que significa que a assinatura é criada com o algoritmo ECDSA e a função de hash SHA256. Você também pode usarES384
eES512
para criar assinaturas com funções de hash SHA384 e SHA512, respectivamente.
A assinatura é criada com a chave privada:
O JWT final mantém a mesma estrutura que o RSA, mas com uma assinatura significativamente menor:
Verifique o JWT
Verificar um JWT é simples como é o processo reverso de criar um JWT:
- Divida o JWT em três partes (cabeçalho, payload e assinatura) usando o delimitador
.
. - Decodifique o cabeçalho e payload com Base64URL.
- Verifique a assinatura com o algoritmo especificado no cabeçalho e a chave pública (para algoritmos assimétricos).
Existem muitas bibliotecas disponíveis para ajudar na verificação do JWT, como o jose para Node.js e navegadores web.
Conclusão
Neste artigo, explicamos brevemente os conceitos centrais do JWT, juntamente com uma visão geral sobre como criar e verificar. Muitos detalhes permanecem inexplorados, e faremos isso em artigos futuros.
Logto utiliza padrões abertos como JWT e OpenID Connect para proteger seus aplicativos e APIs com fluxos de trabalho simplificados para cada desenvolvedor. Se você estiver interessado, pode experimentá-lo gratuitamente (não é necessário cartão de crédito).