Token da Web JSON
A autenticação JWT (JSON Web Token) em APIs REST é um método seguro e sem estado para verificar a identidade de um cliente, garantindo que as solicitações feitas ao servidor sejam válidas e autorizadas. Diferente de sistemas baseados em sessões, que armazenam informações no servidor, o JWT armazena as informações do usuário em um token que é enviado a cada requisição.
O processo de autenticação com JWT segue um fluxo definido:
1 – Login do usuário: O cliente envia suas credenciais (nome de usuário e senha) para um endpoint de autenticação da API.
2 – Verificação e criação do token: O servidor valida as credenciais. Se forem corretas, ele gera um JWT, que contém informações sobre o usuário (conhecidas como “claims”), e assina o token com uma chave secreta.
3 – Envio do token ao cliente: O servidor envia o JWT de volta ao cliente na resposta da requisição de login.
4 – Armazenamento do token: O cliente armazena o token de forma segura (por exemplo, no localStorage do navegador).
5 – Solicitações protegidas: Para acessar recursos protegidos, o cliente inclui o JWT no cabeçalho Authorization de todas as requisições subsequentes, geralmente no formato Bearer <token>.
6 – Validação pelo servidor: O servidor recebe a requisição com o token e valida a assinatura usando a chave secreta. Se a assinatura for válida e o token não estiver expirado, a requisição é processada.
Um JSON Web Token é uma string compacta e autocontida, dividida em três partes separadas por pontos:
- Header (Cabeçalho): Contém metadados sobre o token, como o tipo (
JWT
) e o algoritmo de criptografia utilizado para a assinatura (por exemplo,HS256
ouRS256
). - Payload (Carga): Contém as “claims”, ou seja, as declarações sobre o usuário e outros dados. Essas informações não são criptografadas, mas sim codificadas em Base64, e podem incluir o ID do usuário, tempo de expiração (
exp
), e outras permissões. - Signature (Assinatura): Garante a integridade do token. É criada com a combinação do cabeçalho, do payload e da chave secreta. A assinatura permite que o servidor verifique se o token não foi alterado desde que foi emitido.
Vantagens
- Sem estado (Stateless): O servidor não precisa armazenar informações de sessão. Qualquer servidor com a chave secreta pode validar o token, facilitando a escalabilidade horizontal.
- Performance: A validação do token é feita em memória, sem a necessidade de consultar o banco de dados em cada requisição, tornando o processo mais rápido.
- Segurança: A assinatura garante a integridade dos dados, prevenindo alterações indevidas. Usar HTTPS protege a transmissão do token.
- Interoperabilidade: Por ser um padrão aberto, pode ser usado em diferentes plataformas, facilitando a integração entre serviços e aplicações.
Desvantagens
- Revogação: Após a emissão, um JWT permanece válido até expirar. Revogar um token antes do prazo é complexo e exige mecanismos adicionais (como uma lista negra), pois o servidor não tem controle sobre o token após a emissão.
- Tamanho do token: Se o payload contiver muitos dados, o token pode se tornar grande, aumentando o tráfego de rede.
- Chave secreta comprometida: Se a chave secreta for descoberta por um invasor, ele poderá criar tokens falsificados. É crucial proteger a chave com rigor.
- Exposição de dados: Como o payload é apenas codificado, e não criptografado, informações sensíveis não devem ser armazenadas nele.
Para corrigir e evitar esse problema da Chave secreta comprometida, é preciso adotar práticas rigorosas de gerenciamento de chaves:
- Não armazene a chave no código-fonte: A chave secreta jamais deve estar diretamente no código. Se estiver, qualquer pessoa com acesso ao código, como em um repositório Git, poderá descobri-la. Em vez disso, a chave deve ser tratada como um segredo que é injetado no ambiente de execução da aplicação.
- Utilize variáveis de ambiente: Uma forma comum e eficaz de gerenciar segredos é usando variáveis de ambiente. Em vez de escrever a chave no código, você a armazena em um arquivo
.env
(durante o desenvolvimento) ou define diretamente no ambiente de produção. - Use secrets managers: Para ambientes de produção, a maneira mais segura de gerenciar chaves secretas.
- Use algoritmos de assinatura assimétricos (RS256): Em vez de usar um algoritmo de assinatura simétrico como o
HS256
, que usa a mesma chave para assinar e verificar, use um algoritmo assimétrico como oRS256
..