JWT: Um breve resumo.
Tags: webdev, jwt, backend
Published: 2023-12-08 01:47:25

## 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
```

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
```


### Header

	eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

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
```
### Payload

	eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ

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.
```

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

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.

```javascript
hash(`${base64encodedHeader}.${base64encodedPayload}`, 'secret_key');
```

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/omehmg45b6reij6yo9je.png)

## 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/44k1q7aqpmkhjtc0t49r.png)

> 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