https://a.storyblok.com/f/270183/44257/f72d8ac767/what-are-jwts.png

JWTs: O que são exatamente?

Publicado em September 28, 2023

Tempo de leitura: 7 minutos

Um dos princípios que a equipe de Experiência do Desenvolvedor segue ao escrever tutoriais é que você deve nunca presumir que as pessoas conheçam um determinado assunto técnico. É algo que costumo esquecer e preciso me lembrar regularmente. Se você alguma vez sentir aquele aquela pontada de culpa do outro lado dessa equação, sempre acho útil voltar a este diagrama de Venn atemporal:

Venn Diagram crossing what you know vs. what others know in equal mass

Trabalhar com JWTs constantemente, todos os dias, como parte do meu trabalho, desenvolvendo nosso SDK para PHP, é um desses assuntos. Assim que pesquisei como usamos os JWTs, pronto, estava tudo resolvido. Mas, seguindo meu princípio de “nunca presumir que sei tudo”, percebo que há muitas pessoas que não têm a menor ideia do que são. Além disso, alguns desenvolvedores com certa experiência (mesmo na criação e no uso de APIs) ainda não os utilizaram nem sequer ouviram falar deles. O ritmo de evolução das tecnologias de API tende a ser muito mais lento em empresas maiores ou em expansão do que muitos imaginam. Estamos em 2023 no momento em que este artigo está sendo escrito, mas muitos bancos e empresas farmacêuticas ainda usam SOAP.

Antes de nos aprofundarmos na anatomia dos JWTs, vale a pena observar que este artigo traz exemplos com código. Se você preferir usar algumas de nossas ferramentas para lidar com a criação de JWTs, acesse este artigo de Benjamin Aronov , que mostra como gerar um JWT inteiramente no Painel da Vonage.

O básico

JWT significa JSON Web Token. Em um cenário um tanto confuso de acrônimos, tecnicamente significa JavaScript Object Notation Web Token em sua forma completa. Até sua introdução em um rascunho datado de julho de 2011, as formas mais comuns de autenticação para APIs da web eram a adição de uma chave de API e um segredo não criptografados na string de consulta de uma solicitação ou a autenticação básica, na qual uma das chaves de API ou o segredo (ou ambos) eram submetidos a um hash, geralmente com codificação base64, e passados como um cabeçalho. Um JWT é um hash incluído no cabeçalho de uma solicitação (ou pode estar no corpo, mas isso é menos comum), substituindo os estilos de autenticação mais antigos.

Autenticação atual: os contras

Então, por que é necessária uma nova técnica de autenticação?

Segurança

Esse deve ser o fator mais significativo. Enviar uma chave de API ou um segredo sem criptografia no cabeçalho (ou na string de consulta) a cada solicitação abre uma brecha de segurança bastante significativa. Há mais tráfego com as mesmas credenciais expostas à interceptação e, assim que essas chaves forem comprometidas, você terá deixado toda a sua aplicação ou Account vulnerável.

Costuma haver uma armadilha relacionada à autenticação básica — o método em que se pega {username}:{password} como uma string e a codifica em base64. Muitos desenvolvedores novatos em autenticação de API podem ver o hash resultante e pensar: “Isso parece seguro!”, mas a realidade é que ele é facilmente decodificado em suas duas partes secretas. Por exemplo, acesse https://emn178.github.io/online-tools/base64_decode.html e cole c2VlLXRoYXQtd2FzOmVhc3k=.

A única medida de segurança efetiva que você pode implementar ao usar esses métodos é a rotação de chaves. Dependendo do seu produto de API, grandes bases de código legadas podem nem mesmo ter a capacidade de fazer a rotação de uma combinação de chave principal e segredo (especialmente se elas estiverem vinculadas diretamente a uma Account durante a criação da mesma)

Âmbito

Anteriormente, com os tipos básicos de autenticação, novas chaves eram adicionadas a um portfólio além das suas chaves principais, que você normalmente criava com um conjunto de escopos. Isso pode resultar em uma coleção bastante extensa de chaves usadas para diversos produtos ou consultas específicas — a rotação periódica de um grande número de chaves pode se tornar bastante trabalhosa.

Portabilidade

Assim como no caso do escopo, segredos fixos como esse mantêm as permissões, os escopos e o acesso à API dos usuários armazenados no servidor. Isso os torna estáticos e pouco flexíveis quando se trata de uma API mais complexa, com muitos parâmetros a serem considerados ao receber uma solicitação.

Anatomia de um JWT

Os JWTs têm como objetivo resolver essas três questões. Veja a seguir como eles são estruturados:

Informações do cabeçalho

Quando nos referimos a “cabeçalho”, vale a pena observar que se trata o cabeçalho do JWT e não um cabeçalho de solicitação HTTP.

O servidor precisa de informações sobre como o JWT foi criado. Devido a esse requisito, o cabeçalho conterá informações sobre como o JWT foi criado em duas chaves:

  • alg o que, em muitos casos, provavelmente será definido por padrão como HS256

  • typ que identifica o token como um JWT (à medida que o padrão evolui, é provável que surjam iterações ou novas versões desse tipo de token)

Carga útil

A carga útil de um JWT assume a forma de reivindicações, que são uma série de pares chave-valor contendo informações sobre o JWT. As reivindicações reservadas mais comuns (ou *Nomes de Reivindicações Registradas) são as seguintes:

  • iss: a origem do JWT (aplicativo, organização etc.)

  • sub: um valor único para o emissor, ao qual as demais reivindicações se referem no contexto do JWT

  • exp: a data de validade do JWT

  • iat: quando o JWT foi criado (emitido em)

  • jti: um identificador único para este JWT

Os JWTs são muito úteis para autenticação porque é possível adicionar a eles claims personalizados que sejam relevantes para o aplicativo que os utiliza. Veja, por exemplo, o JWT da Vonage — ao usar nossas APIs que suportam autenticação por JWT, uma reivindicação personalizada application_id é utilizada. A Vonage pode verificar o JWT em relação à chave SSH privada do seu Account (que terá sido usada no lado do cliente solicitante para gerar o JWT) e, se for válido, a solicitação pode ser rapidamente encaminhada para a instância correta da aplicação dentro das APIs da Vonage.

Como criar um JWT: Edição PHP

Como desenvolvedor PHP da minha equipe, vou gerar um JWT válido com o mínimo possível de linhas de código para mostrar como é relativamente simples começar. Eis o que precisamos:

  • Um ID de aplicação do Painel de Controle.

  • Uma cópia da chave privada do aplicativo foi baixada do Painel de Controle.

Você pode acessar ambas nas configurações do aplicativo aqui:

Screenshot of Vonage Dashboard, accessing an Application's Settings

Para isso, usaremos o gerador de JWT em PHP da Vonage, disponível no GitHub. Para instalá-lo, você precisará do Composer.

composer require vonage/jwt

E agora, o código:

<?php

require_once "vendor/autoload.php";

$applicationId = "78d335fa-323d-0114-9c3d-d6f0d48968cf";
$privateKey = file_get_contents('private.key');
$generator = new Vonage\JWT\TokenGenerator($applicationId, $privateKey);
$jwt = $generator->generate();

Pronto!

Para usar isso em uma solicitação, você precisará adicioná-lo como um cabeçalho. Precisaremos de um cliente HTTP compatível com PSR-18 para enviá-lo. Escolhi o HTTPClient do Symfony para mostrar como é possível fazer isso com poucas linhas de código. Para instalá-los, adicione-os ao seu projeto com o Composer:

composer require symfony/http-client

E, em seguida, vamos enviar uma solicitação POST para a Messages API for Vonage usando nosso JWT:

use Symfony\Component\HttpClient\HttpClient;

$payload = [
	'message_type' => 'text',
	'text' => 'Using a JWT to send Vonage a request!',
	'to' => '44779999999',
	'from' => '44779499999',
	'channel' => 'sms'
]

$client = HttpClient::create();

$client->request('POST', 'https://api.nexmo.com/v1/messages/', [
	'headers' => [
		'Authorization' => 'Bearer ' . $jwt,
		'Content-Type' => 'application/json',
	],
	'json' => $payload
])

E pronto! Claro, esse é apenas um exemplo básico de como fazer isso. Se você quiser fazer uma integração completa, recomendo usar nosso SDK para Core PHP, que resolve muitos problemas. Se você não gosta de PHP, tudo bem! Também temos SDKs para Node, Java, Python, Ruby e .NET!

Compartilhar:

https://a.storyblok.com/f/270183/400x385/12b3020c69/james-seconde.png
James SecondePromotor Sênior de Desenvolvimento em PHP

Sou ator formado, com uma dissertação sobre stand-up comedy, e comecei a me dedicar ao desenvolvimento em PHP por meio dos encontros da comunidade. Você pode me encontrar dando palestras e escrevendo sobre tecnologia, ou ouvindo e comprando discos curiosos da minha coleção de vinil.