Eu, eu mesmo e… JWT
JSON Web Token — JWT
Neste post explicarei um pouco sobre como funciona o padrão de autenticação por token JSON Web Token — JWT (RFC 7519).
O que é JWT?
Do site oficial:
JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object.
– http://jwt.io
Traduzindo, é um padrão aberto que define uma forma compacta e auto-contida para transmitir de forma segura, informações entre duas partes como objeto JSON.
Estrutura
O token é formado por 3 partes separador por pontos (.):
- Header
- Payload
- Signature
* Não vou traduzir porque fica horrível.
Ou seja, teríamos algo assim
xxxxx
.
yyyyyy
.
zzzzzz
* As quebras de linha são para facilitar a visualização.
Header
Consiste em 2 partes encodados em Base64:
- O tipo (JWT)
- e o algoritmo de hash usado (HMAC SHA256 ou RSA).
{
“alg” : “HS256”,
“typ” : “JWT”
}
Então teríamos a primeira parte
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.
yyyyyy
.
zzzzzz
Payload
Contém a informação em si compartilhada entre as partes. Existe tipos de informações, mas não entrarei em detalhes. Basicamente, é o dado de interesse transmitido.
Também encodado em Base64:
{
"nome" : "Fulano",
"admin" : true
}
Então teremos:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.
eyJub21lIjoiRnVsYW5vIiwiYWRtaW4iOnRydWV9
.
zzzzzz
Signature
Para assinar o token, usamos a Header, Payload, o algoritmo definido na header, um secret.
Assim, no exemplo, foi usado o HMAC SHA256 (HS256), então teríamos:
HMACSHA256(header + “.” + payload, secret)
Onde header e payload já estão encodados em Base64.
Finalmente:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.
eyJub21lIjoiRnVsYW5vIiwiYWRtaW4iOnRydWV9
.
IShPdPgMqjygLcv6FpePbFuRLJHBTdeKSNDQIpR-X2E
Como funciona?
Quando o usuário faz o login com sucesso, o servidor retorna o JWT que deve ser salvo localmente, seja num cookie, no localStorage, etc.
Assim, e toda requisição, envia-se o token para o servidor.
O servidor recebe e, dado que ele possui o secret e o algoritmo que está na header, consegue validar a informação do payload e usá-la sem precisar ir ao banco de dados todas as vezes.