DEV Community

Cover image for JWT: Um breve resumo.
Julian Barbosa
Julian Barbosa

Posted on

JWT: Um breve resumo.

Para que serve?

Tokens JWT são tokens "autossuficientes" que servem para realizar troca de informações de forma segura entre aplicações no formato JSON

Self-Contained

Os tokens carregam dentro de si todas as informações necessárias para validá-lo. Ou seja: são autossuficientes.

Stateless

Sendo os tokens autossuficientes, nós não precisamos salvar anda no servidor em um cache ou banco de dados, por isso não possuem estado.

Anatomia de um Token JWT

A Anatomia de um token JWT consiste em três strings criptografadas que são separadas por um ponto, onde cada string representa uma parte do JWT, seguindo a seguinte estrutura:

header.payload.signature
Enter fullscreen mode Exit fullscreen mode

Falaremos um pouco mais sobre cada uma das partes que compõe o token e abaixo segue um exemplo de um token jwt real retirado do site https://jwt.io/

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Enter fullscreen mode Exit fullscreen mode

Header

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Enter fullscreen mode Exit fullscreen mode

O Header do JWT é onde armazenamos informações como o tipo de token (JWT) e o algoritmo usado para gerar a assinatura do nosso token.

{
  "alg": "HS256",
  "typ": "JWT"
}
alg = algorítmo utilizado para a geração do token
typ = tipo de token
Enter fullscreen mode Exit fullscreen mode

Payload

eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
Enter fullscreen mode Exit fullscreen mode

O Payload é o lugar onde salvamos as informações do token: quando foi gerado, data de expiração, id do usuário que gerou, etc...

Dentro do payload podemos inserir quaisquer dados que quisermos, porém abaixo fica um exemplo de uma convenção utilizada:

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

sub = Subject
iat = issued at, data de quando o token foi gerado.
Enter fullscreen mode Exit fullscreen mode

Note que o payload cresce proprocionalmente à quantidade de itens inseridas, portanto não envie o banco de dados inteiro no seu payload.

Tanto o Header quanto o Payload são encodados em base64, uma codificação simples que converte uma string pra outra string, onde é possível fazer o decode de forma fácil em qualquer lugar, portanto não é recomendado inserir dados sensíveis no token.

Assinatura

SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Enter fullscreen mode Exit fullscreen mode

A Assinatura é a parte mais importante do JWT pois ela é quem garante que o token foi gerado pela sua aplicação e que não foi modificado após ser gerado.

HS256 é uma sigla para Hash-based Message Authentication Code

Pra gerar o hash e autenticar nossa assinatura é necessário o header, payload e uma chave secreta, que preferencialmente fica numa variável de ambiente no backend.

hash(`${base64encodedHeader}.${base64encodedPayload}`, 'secret_key');
Enter fullscreen mode Exit fullscreen mode

A "autenticação" da assinatura é feita através do HMAC (Código de Autenticação de Mensagem Baseado em Hash), gerando a hash utilizando uma chave secreta e depois garantir que foi gerada pela nossa aplicação, utilizando algum algoritmo de criptografia (SHA256 por exemplo)

O HMAC é como uma função pura, o retorno é exatamente o mesmo dado os mesmos dados de entrada (header, payload e secret) com isso é possível validar a integridade da assinatura do token

Como validamos o token?

Basicamente geramos o mesmo hash no backend: Ao receber o token JWT, extraímos o header, payload e geramos novamente a hash utilizando nossa secret_key, sendo assim possível comparar o token recebido na requisição com o token enviado pelo backend na autenticação do usuário.

Dessa forma, a validação é feita utilizando as assinaturas geradas de ambos os tokens, caso o payload enviado pelo usuário tenha sido alterado a assinatura (HMAC) também será alterada, invalidando o token.

Caso alguém tenha acesso à nossa secret_key, seria possível gerar um hash válido, por isso não devemos expor essa secret_key para ferramentas de controle de versão no nosso backend.

Diagrama de validação do token JWT

Primeiro envio do token

O primeiro envio e geração do token é realizado quando o usuário se autentica na aplicação, retornamos o token para que o usuário salve para futuras requisições, como no localStorage ou nos cookies do navegador

Diagrama de geração do token JWT

Note que, independente do que você fizer, não é recomendado salvar o token JWT no localStorage ou sessionStorage. Caso algum dos scripts que você incluiu na sua aplicação esteja comprometido, pode acessar todos os tokens do usuário. É recomendado salvar dentro de um cookie httpOnly para manter seu token JWT seguro. Esse é um cookie especial que só é enviado em requisições HTTP para o servidor e não é acessível para o javascript rodando no navegador

Top comments (2)

Collapse
 
lixeletto profile image
Camilo Micheletto

Mano, adorei as anotações e as imagens que tu colocou! Ficou muito claro o entendimento

Collapse
 
julian_barbosa profile image
Julian Barbosa

Valeu <3