Um JSON Web Token, RFC 7519, e uma forma compacta de transportar um conjunto de alegacoes de
uma parte para outra para que o lado receptor possa confiar quem as enviou, ou ao
menos verificar que nada mudou em transito. Todo JWT que voce vera em
um cabecalho Authorization: Bearer sao as mesmas tres pecas unidas por pontos:
header.payload.signature.
As tres partes
O cabecalho e a carga util sao cada um um objeto JSON, codificado em base64url. O
cabecalho nomeia o algoritmo de assinatura e o tipo de token, tipicamente algo
tao pequeno quanto {"alg":"HS256","typ":"JWT"}. A carga util contem as alegacoes: os
dados que o token realmente transporta, mais um punhado de nomes registrados com
significados definidos, iss (emissor), sub (assunto), aud (publico), iat
(emitido em), nbf (nao antes de) e exp (expiracao) e jti (um id de token). Nenhum
disso e obrigatorio alem do que o emissor escolher incluir, e por isso que dois JWTs
de dois servicos diferentes podem transportar alegacoes completamente diferentes.
A assinatura nao e JSON de jeito nenhum. E o resultado de executar o cabecalho e
a carga util, ainda em sua forma codificada, pelo algoritmo nomeado no cabecalho,
HS256 (HMAC com um segredo compartilhado) e RS256/ES256 (RSA ou
ECDSA com uma chave privada) sendo os que voce mais encontrara. Decodificar a assinatura em base64url
lhe da bytes brutos sem nenhuma estrutura adicional para ler.
Codificado nao e criptografado
Base64url e uma codificacao, nao uma cifra. Qualquer pessoa com um JWT pode decodificar o cabecalho e a carga util com nada mais que um editor de texto, o que e exatamente o que o Decodificador JWT faz. Isso significa que um JWT nunca e o lugar certo para qualquer coisa que voce nao colocaria em uma URL: uma senha, um numero de cartao de credito, um nome completo que alguem nao concordou em expor. Se uma carga util precisa permanecer confidencial em vez de apenas a prova de adulteracao, isso chama por um token de Encriptacao Web JSON, um formato diferente e menos comum, nao um JWT assinado com um algoritma mais forte.
Decodificar nao diz nada sobre confianca
Essa e a parte da qual decodificadores mais sao culpados, entao vale a pena afirmar claramente: ler as alegacoes de um JWT nao prova nada sobre se o token e genuino. Verificar uma assinatura significa recalcula-la com o segredo real ou a chave publica com a qual o token foi assinado e verificar se corresponde, byte por byte. Um decodificador que apenas divide o token em seus pontos e decodifica duas das tres partes em base64url, o que todo decodificador puro do lado do cliente faz, nao tem acesso a essa chave e nao pode fazer essa verificacao. Ele pode dizer o que um token alega. Nao pode dizer se voce deve acreditar.
Um token bem formado, decodificado limpo, ainda pode ser falsificado, expirado, ou
assinado com uma chave que nunca foi destinada a emiti-lo. exp e nbf valem a pena
ser verificados em toda decodificacao por exatamente essa razao: um token alem de sua
expiracao, ou ainda nao valido, e invalido independentemente de sua assinatura
estar correta, e ler esses dois campos como os timestamps que representam
em vez de numeros brutos e a maneira mais rapida de capturar isso de relance.
Para que isso serve
Apesar dessa limitacao, decodificar sem verificar tem usos reais, diarios: ler que escopos um token de acesso foi emitido durante a depuracao de uma integracao de API, verificar se o token que sua aplicacao acabou de receber realmente expirou (em vez de adivinhar a partir de um vago 401), ou inspecionar o que contem o token de uma terceira parte antes de decidir se seu servidor precisa confiar nele de forma alguma. Nada disso requer a chave de assinatura, apenas o token em si.
Cole um no Decodificador JWT e ele separa o cabecalho, as alegacoes registradas e a carga util restante em suas proprias linhas, sinaliza imediatamente um token expirado ou ainda nao valido, e mostra os bytes brutos da assinatura sem fingir ter verificado contra nada.