CodeBlogLogo CodeBlog

JWT: Autenticação em APIs REST com PHP

JWT: Autenticação em APIs REST com PHP

Criando um token de autenticação usado em API REST com Json Web Token (JWT) em PHP

1156
Allain Estevam

O modelo de API foi usado recentemente em aplicativos. Isso ocorre porque os aplicativos não podem mais depender apenas de seus próprios dados, para que um projeto veja totalmente seu potencial, ele deve ter aplicativos de terceiros, misturar-se a outros aplicativos e ter seus dados facilmente acessados ​​pelos desenvolvedores.

Pense em como o Facebook fornece uma API para capturar seus dados (contanto que você esteja autenticado, é claro). O Facebook também permite que aplicativos de terceiros e outros serviços acessem seus dados. Tudo isso é feito por meio de uma API.

Agora, quando falamos sobre criar nossas próprias APIs, sempre haverá o tópico de: como proteger nossa própria API?

Hoje vamos ver um padrão (JSON Web Tokens) e como criá-los.

 

O que são tokens Web JSON?

Json Web Token (JWT) é uma forma elegante e segura de tratar autenticação em APIs. JWT não é um simples token gerado a partir de dados randômicos. JWT contém informações e metadados que descrevem a entidade do usuário, dados de autorização, validade do token, domínio válido, etc.

Funciona de forma stateless, ou seja, sem manter estado no lado do servidor (como Cookies e Sessões). Dados podem ser inspecionados, é compatível com OAuth2, possui controles de expiração, segurança e possui implementações em diferentes linguagens de programação.

Os JSON Web Tokens funcionam em diferentes linguagens de programação: as JWTs funcionam em .NET, Python, Node.js, Java, PHP, Ruby, Go, JavaScript e Haskell. Então você pode ver que eles podem ser usados ​​em muitos cenários diferentes.

As JWTs são independentes: elas carregam toda a informação necessária dentro de si. Isso significa que um JWT poderá transmitir informações básicas sobre si mesmo, uma carga útil (geralmente informações do usuário) e uma assinatura.

As JWTs podem ser transmitidas com facilidade: como as JWTs são independentes, elas são usadas perfeitamente dentro de um cabeçalho HTTP ao autenticar uma API. Você também pode passar pelo URL.

 

Como é um JWT?

Um JWT é fácil de identificar. São três partes separadas por (.) ponto.

aaaaaaaaaa.bbbbbbbbbbb.cccccccccccc

JWT: Autenticação em APIs REST com PHP

Vamos dividir as 3 partes e ver o que cada uma contém.

 

Quebrando um Token Web JSON

Cada token é dividido em três partes e cada parte é separada por um ponto.

  • Cabeçalho: Contém informações sobre o tipo de token, geralmente JWT, e o algoritmo de hash usado, por exemplo, HMAC SHA256 ou RSA.
  • Payload: Contém todas as informações que você deseja transferir sobre o usuário, por exemplo, o identificador de usuários, um ID.
  • Assinatura: Isso protege o token e é um hash do cabeçalho e da carga codificados, junto com um segredo.

 

Header (Cabeçalho)

O cabeçalho carrega 2 partes:

  • declarando o tipo, que é JWT
  • o algoritmo de hash para usar ( HMAC SHA256 neste caso)

Aqui está um exemplo:

{ 
"typ": "JWT",
"alg": "HS256"
}

Agora, uma vez que isso é feito deve-se usar o base64encode, e temos a primeira parte do nosso token da web JSON!

// Cria token header
$header = json_encode(['typ' => 'JWT', 'alg' => 'HS256']);

// Codifica Header para Base64Url
$base64UrlHeader = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($header));

// Resultado
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9

 

Payload (Carga útil)

A carga útil será responsável pela maior parte do nosso JWT, também chamado de Reclamações do JWT. É aqui que vamos colocar as informações que queremos transmitir e outras informações sobre o nosso token.

Existem várias parametros que podemos fornecer. Isso inclui nomes de reivindicações registrados, nomes de reivindicações públicas e nomes de reivindicações particulares.

Reivindicações registradas

Parametros que não são obrigatórias cujos nomes estão reservados para nós. Esses incluem:

  • iss: o emissor do token. Pode usar o dominio onde está sua api. Ex: api.dominio.com
  • sub: O assunto do token.
  • aud: O público do token.
  • exp: Essa provavelmente será a reivindicação registrada mais usada. Isso definirá a expiração no valor NumericDate. A expiração DEVE ser depois da data/hora atual.
  • nbf: Define o tempo antes do qual o JWT NÃO DEVE ser aceito para processamento.
  • iat: O horário em que o JWT foi emitido. Pode ser usado para determinar a idade do JWT.
  • jti: Identificador exclusivo para o JWT. Pode ser usado para impedir que o JWT seja repetido. Isso é útil para um token de uso único.
Reivindicações públicas

Essas são as afirmações que nos criamos, como nome de usuário, informações e outras informações importantes.

Reivindicações particulares

Um produtor e consumidor podem concordar em usar nomes de reivindicação que sejam privados. Estes estão sujeitos a colisão, portanto, use-os com cautela.

 

Abaixo um exemplo de Payload

Nossa carga útil de exemplo tem duas reivindicações registradas ( iss e exp ) e duas declarações públicas ( name , admin ).

{ 
"iss": "codeblog.com.br",
"exp": 1300819380,
"name": "Whallysson Estevam",
"admin": true
}

Isto será codificado (com base64) para:

// Cria o token payload
$payload = json_encode([
"iss" => "codeblog.com.br",
"exp" => 1300819380,
"name" => "Whallysson Estevam",
"admin" => true
]);

// Codifica Payload para Base64Url
$base64UrlPayload = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($payload));

// Resultado
eyJpc3MiOiJjb2RlYmxvZy5jb20uYnIiLCJleHAiOjEzMDA4MTkzODAsIm5hbWUiOiJXaGFsbHlzc29uIEVzdGV2YW0iLCJhZG1pbiI6dHJ1ZX0

Essa será a segunda parte do JSON Web Token.

 

Signature (Assinatura)

A terceira e última parte do nosso JSON Web Token será a assinatura. Essa assinatura é composta de um hash dos seguintes componentes:

  • o cabeçalho;
  • a carga útil;
  • segredo;

É assim que conseguimos a terceira parte do JWT:

// Criando a Assinatura Hash
$secret = 'minha-chave'; //sua chave secreta
$signature = hash_hmac('sha256', $base64UrlHeader . "." . $base64UrlPayload, $secret, true);

// Codifica a Assinatura para Base64Url
$base64UrlSignature = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($signature));

O segredo é a assinatura do servidor. É assim que nosso servidor poderá verificar os tokens existentes e assinar novos.

Isso nos dá a parte final do nosso JWT.

mohMIDGciCXqR-jYDVyWfLBSKw8K_p9X-gJFj3VLBDk

Agora temos nosso JSON Web Token completo:

// Criando o JWT
$jwt = $base64UrlHeader . "." . $base64UrlPayload . "." . $base64UrlSignature;

// Nosso JWT
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJjb2RlYmxvZy5jb20uYnIiLCJleHAiOjEzMDA4MTkzODAsIm5hbWUiOiJXaGFsbHlzc29uIEVzdGV2YW0iLCJhZG1pbiI6dHJ1ZX0.mohMIDGciCXqR-jYDVyWfLBSKw8K_p9X-gJFj3VLBDk

 

O script

// Cria token header
$header = json_encode(['typ' => 'JWT', 'alg' => 'HS256']);

// Codifica o Header para Base64Url
$base64UrlHeader = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($header));

// Cria o token payload
$payload = json_encode([
"iss" => "codeblog.com.br",
"exp" => 1300819380,
"name" => "Whallysson Estevam",
"admin" => true
]);

// Codifica Payload para Base64Url
$base64UrlPayload = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($payload));

// Criando a Assinatura Hash
$secret = 'minha-chave'; //sua chave secreta
$signature = hash_hmac('sha256', $base64UrlHeader . "." . $base64UrlPayload, $secret, true);

// Codifica a Assinatura para Base64Url
$base64UrlSignature = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($signature));

// Criando o JWT
$jwt = $base64UrlHeader . "." . $base64UrlPayload . "." . $base64UrlSignature;

// Nosso JWT
echo $jwt;

 

A Auth0 criou um ótimo site (https://jwt.io/) para testar e testar como as JWTs são feitas. Você pode ver como você muda o conteúdo na hora, você pode ver o JWT sendo atualizado imediatamente.

Para uma explicação de como funciona o Json Web Token (JWT), aqui tem um video de uma palestra com Ivan Rosolen, Head de Inovação Arizona, que fala sobre Json Web Token no PHP Experience 2016.

 

Conclusão

O padrão JSON Web Token pode ser usado em várias linguagens de programação e é rápido e facilmente intercambiável.

Você pode usar o token em um URL, um parâmetro POST ou um cabeçalho HTTP. A versatilidade do JSON Web Token nos permite autenticar uma API de maneira rápida e fácil, transmitindo informações por meio do token.

 

COMENTÁRIOS

Posts Relacionados!