Autenticação usando JSON Web Token (JWT)

O JWT é uma ferramenta que faz parte do sistema de autenticação em um software web.

O JWT é nada mais que um arquivo de texto que o usuário de um website (que utiliza autenticação) guarda dentro do navegador de seu computador para que não precise digitar senha e login toda vez que tiver que fazer uma ação no sistema (criar/apagar/ver qualquer dado dentro do sistema).

Ou seja, sem a tecnologia do JWT o usuário teria que informar seu login e senha a cada ação que deseja realizar no sistema.

Mas o JWT por si só não faz a autenticação! É preciso de mais 2 ferramentas para a autenticação ficar completa.

  1. Precisamos de um banco de dados (ou algo do tipo) que guarde logins e senhas dos usuários.
  2. Precisamos de uma biblioteca geradora de JWTs no servidor

E como tudo isso funciona junto?

1 - Cliente envia login e senha

Um usuário entra num website e envia seu login e senha para o servidor do website via HTTPS (enviar o login e senha via POST no corpo da mensagem para que eles não sejam impressos nos logs).

2 - Servidor confere login e senha

O servidor recebe a mensagem e verifica no banco de dados (ou em outro lugar) se o login existe e se a senha está correta.

3 - Servidor cria um JWT decodificado

Se o login e a senha estiverem corretos, o servidor cria um pequeno arquivo texto contendo o seguinte:

//HEADER:{  "alg": "HS256",  "typ": "JWT"}//PAYLOAD:{  "sub": "1234567890",  "name": "John Doe",  "iat": 1516239022}

Esse arquivo é o arquivo JWT decodificado.

No HEADER temos:
"alg", o tipo do algoritmo de criptografia a ser usado
"typ", o tipo do token a ser utilizado, JWT

No PAYLOAD temos:
sub (subject) = Entidade à quem o token pertence, normalmente o ID/Login do usuário;
iss (issuer) = Emissor do token;
exp (expiration) = Timestamp epoch de quando o token irá expirar;
iat (issued at) = Timestamp epoch de quando o token foi criado;
aud (audience) = Destinatário do token, representa a aplicação que irá usá-lo.
E qualquer outro dado que queria colocar aqui...

4 - Servidor codifica o JWT decodificado

Nessa etapa é preciso usar uma biblioteca geradora de JWT para a linguagem de programação usada no servidor.

Essa biblioteca pegará o JWT decodificado e assinará/codificará ele com uma chave secreta (que pode ser única para sempre, desde que não seja vazada).

O JWT decodificado é algo tipo isso:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhbGVhdGl0dXNAYWxlYXRpdHVzLm1lIiwibmFtZSI6IkFsZWF0aXR1cyIsImlhdCI6MTUxNjIzOTAyMn0.esUoBdXjSOhC1VH6F4gtrmYKwrgbID7ima70x5aE8Pk

5 - Servidor envia o JWT codificado para o Cliente

O Servidor envia o JWT codificado para o cliente. O cliente pode guardá-lo em um cookie com a mesma data de expiração. O cliente enviará esse JWT codificado ao servidor todas vezes que quiser se comunicar pelo cabeçalho (header) HTTPS.

Boas Práticas com JWT

Use sempre JWTs com criptografia assíncrona (não use HMAC).

Não confie no campo "alg" do JWT. Não use ele como base para fazer a verificação do JWT pois se seu token for assinado por RSA mas você estiver aceitando o algoritmo HMAC, você está sucetível a um ataque.

Disponibilize as chaves públicas do seu JWT (chamadas de JWK set) dessa forma em uma url.
https://docs.cidaas.com/standard-endpoints/server-jwk-set.html

Não use JWT para armazenar dado de sessão (?) Essa é polêmica.
https://curity.io/resources/learn/jwt-best-practices/

Boas práticas JWT pelo OWASP
https://cheatsheetseries.owasp.org/cheatsheets/REST_Security_Cheat_Sheet.html
https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/06-Session_Management_Testing/10-Testing_JSON_Web_Tokens

Attacking and securing JWT - Apresentação
https://owasp.org/www-chapter-vancouver/assets/presentations/2020-01_Attacking_and_Securing_JWT.pdf

Críticas ao uso de JWTs

Pare de usar JWTs para armazenar dado de sessões. Polêmica também.
http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-for-sessions/

Referências

Entendendo JWT
https://medium.com/tableless/entendendo-tokens-jwt-json-web-token-413c6d1397f6

JWT.io
https://jwt.io/

Gerando e Lendo JWT no PHP
https://imasters.com.br/back-end/entendendo-o-jwt

Boas práticas de segurança com JWT
https://blog.logrocket.com/jwt-authentication-best-practices/

Qual a diferença entre JWT e Cookies?
https://stackoverflow.com/questions/37582444/jwt-vs-cookies-for-token-based-authentication

You should also read: