Conhecendo o JWT

Fala devs, tudo bem? Espero sinceramente que sim!

Vamos conhecer um pouco sobre este token que é bastante utilizando hoje em dia! O famoso JWT ou Json Web Token!

Nesta primeira parte vamos conhecer como é formado este token e o que permeia a especificação dele.

O JWT

O JWT é um padrão aberto, referido pela RFC 7519, que permite a troca de informações entre duas partes, por meio da troca de tokens. Por meio de uma assinatura no token é possível ainda, trazer uma segurança e uma confiabilidade ao token.

O JWT geralmente está atrelado, quando nos referimos a API, ao momento de autorização, quando precisamos acessar um determinado endpoint que necessite de uma identificação válida por meio do client para consumo daquele recurso.

Vamos conhecer mais sobre como é formado o JWT para entendermos melhor onde entra cada coisa e onde a segurança é adicionada.

Entendendo a Formação do Token

Antes de entendermos o token é importante ressaltar que o JWT faz parte de um guarda-chuva maior a qual, junto dele, formam a especificação. Denominamos de JOSE todos os elementos responsáveis por termos o token JWT a mãos. O JOSE ou Json Object Signing and Encryption é formado pelas specs abaixo:

  • JWT: Json Web Token, o token propriamente dito;
  • JWE: Json Web Encryption, a criptografia para assinatura do token;
  • JWA: Json Web Algorithms, sobre os algoritmos para assinatura do token;
  • JWK: Json Web Keys, as chaves para assinatura;
  • JWS: Json Web Signature, sobre a assinatura do token.

O jwt é formado de três partes:

  • header: contêm algumas informações do token, como o tipo e o algoritmo utilizado na assinatura;
  • content/payload: contêm o conteúdo a ser trafegado, neste vai as claims definidas pela spec como o tempo de expiração do token por exemplo e informações adicionadas por nós no momento da geração;
  • signature: a assinatura do token, que é formada pela concatenação do header junto do ponto de separação (vamos entender ele mais abaixo) mais o payload, e é assinado usando uma chave escolhida pelo usuário com o algoritmos definido no header.

O ponto mencionado logo acima´é o que define a separação de cada parte do token jwt, o nosso caractere coringa vamos dizer assim. Além das informações mencionadas acima, cada parte destas, separadamente, além de serem um json recebem um base64 para podermos trafegar o token nos cabeçalhos HTTP ou em parâmetros de URL.

Veja o exemplo de um token JWT:

Acima temos um JWT e perceba o caractere ponto reforçado em vermelho que separa cada uma das partes do token: o header, o content/payload e a signature (assinatura).

Se nós pegarmos cada parte deste token e jogarmos um base64 decode teremos acesso ao conteúdo do mesmo. Podemos debugar este token no site http://jwt.io criado pela empresa Auth0.

Conteúdo do header (print do site jwt.io):

Neste header informamos o tipo do token, no caso JWT o algoritmo HMAC SHA256 e ainda, temos um identificador único do token, o JTI.

Vamos ver o que temos no payload:

No conteúdo do token ou payload temos algumas informações, chamadas de claims, a mais em relação ao header, justamente por ser onde se encontram as informações trafegadas tanto as definidas pela spec quanto as adicionadas por nós mesmos como id do usuário, email e etc.

Existem algumas claims reservadas, que não são obrigatórias, mas que ajudam na unicidade do token.

Vamos a elas abaixo:

  • jti: Json Token Identifier ou ID único para o token;
  • iat: Issued At, usado para determinar a idade do token;
  • nbf: Not Before, usado para especificar a partir de quando o token passa a ser válido;
  • aud: Audience, quem vai consumir o seu token;
  • exp: Expiration, tempo para utilização do token;
  • iss: Issuer, quem emitiu o token;

No conteúdo do token acima adicionei uma claim própria o uid que se refere ao id do usuário que logou na aplicação e gerou o token. Vale ressaltar que ainda temos uma claim reservada chamada de sub (subject) sujeito do token que também pode se referenciar ao id do usuário como sujeito.

Vamos ao resultado da assinatura do token:

Verifique que o resultado para a assinatura do nosso token é como ele é formado, pegamos o hash base 64 do header, concatenamos com nosso caractere coringa, o ponto, concatenamos com o payload. Aplicamos então a criptografia com a chave escolhida.

No meu caso quando gerei o token, usei a chave testing, lembrando que essa chave de geração é de competência da sua aplicação e só e somente ela deve conhecer esta chave.

Disclaimers sobre o Token

Perceba que temos nos claims e no conteúdo do header palavras abreviadas, exclusivamente para evitar que o token fique muito grande. O token vai crescer dada a quantidade de informações exclusivamente do seu payload que é o ponto onde você pode adicionar mais informações dentro do especificado.

Outro ponto sobre o payload, de forma alguma jogue dados delicados no conteúdo do token como passwords ou dados delicados dentro da sua regra de negócio. Percebemos que o token é um base64 em cima de cada parte, onde temos um json e com isso podemos verificar o conteúdo do token.

Onde entra a segurança do token?

Para concluirmos vamos falar onde entra a segurança, já que podemos fazer um decode no token e ta lá! o conteúdo do token na cara!

O que traz a confiabilidade do token, pelo menos enquanto não quebram a criptografia do hash rsrsrs, é justamente a parte três do token.

Vamos relembrar como ela é gerada:

  • O hash é aplicado no base64 do header;
  • Junto do caractere coringa, o ponto;
  • Junto do base64 do payload;
  • É usado uma chave para realizar a criptografia que somente a sua aplicação conhece. E por fim, no resultado do hash hmac efetuamos um base64 encima.

Se por ventura alguém pegar o token e modificar seu conteúdo, quando formos fazer o teste da assinatura deste token modificado não irá bater com o token gerado por nossa aplicação, uma vez que o payload (que usamos para gerar nossa assinatura inicialmente) ou outra parte foi modificada.

Vale ressaltar também que, geralmente em APIs onde temos endpoints sob autorização e esta autorização necessita de um token e este venha a ser o jwt, a pessoas que está sob posse do token terá acesso a tudo daquele endpoint. Então é importante você sempre definir um tempo de vida para o token, que se cair em mãos erradas o token pode vir a ser inválido limitando o usuário mal intencionado a consumir os dados antes permitida ao usuário solicitante do token.

Conclusões

Bom por enquanto é isso, vimos o que permeia os tokens JWT, na segunda parte desta série veremos como podemos gerar um token JWT na mão para entendermos melhor os pontos aqui mostrados.

Qualquer acréscimo ou dicas ou feedback escreva aí nos comentários se eu esqueci de algo ou existe algo errado só me escrever abaixo também.

Forte abraço e que esse material possa te ajudar imensamente.

Fiz um vídeo sobre o assunto comentado neste post:

Inscreva-se em nosso canal clicando aqui!

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *