Makrosites

Suas ideias em realidade digital!

JWT em PHP: autenticação segura para APIs (exemplo completo)

JWT em PHP: autenticação segura para APIs (exemplo completo)

O que é JWT e por que usar em APIs PHP?

JWT (JSON Web Token) é um padrão aberto para autenticação stateless, muito usado em APIs REST. Em vez de sessão no servidor, o usuário recebe um token assinado, que é enviado a cada requisição.

JWT é ideal para:

---

Fluxo de autenticação com JWT

  1. Usuário faz login (email/senha)
  2. API valida credenciais
  3. API gera um JWT assinado
  4. Front armazena o token
  5. Requisições enviam Authorization: Bearer TOKEN
---

Estrutura básica do JWT

HEADER.PAYLOAD.SIGNATURE
---

Implementação JWT em PHP puro (sem biblioteca)

Para fins didáticos, vamos implementar JWT manualmente. Em produção, use bibliotecas como firebase/php-jwt.

---

1) Funções auxiliares JWT

<?php
function base64UrlEncode(string $data): string {
  return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}

function base64UrlDecode(string $data): string {
  return base64_decode(strtr($data, '-_', '+/'));
}
---

2) Gerar token JWT

<?php
function generateJWT(array $payload, string $secret, int $expSeconds = 3600): string {
  $header = ['alg' => 'HS256', 'typ' => 'JWT'];

  $payload['iat'] = time();
  $payload['exp'] = time() + $expSeconds;

  $base64Header  = base64UrlEncode(json_encode($header));
  $base64Payload = base64UrlEncode(json_encode($payload));

  $signature = hash_hmac(
    'sha256',
    "$base64Header.$base64Payload",
    $secret,
    true
  );

  $base64Signature = base64UrlEncode($signature);

  return "$base64Header.$base64Payload.$base64Signature";
}
---

3) Validar token JWT

<?php
function validateJWT(string $jwt, string $secret): array|false {
  $parts = explode('.', $jwt);
  if (count($parts) !== 3) return false;

  [$header, $payload, $signature] = $parts;

  $validSignature = base64UrlEncode(
    hash_hmac('sha256', "$header.$payload", $secret, true)
  );

  if (!hash_equals($validSignature, $signature)) return false;

  $data = json_decode(base64UrlDecode($payload), true);

  if (!$data || $data['exp'] < time()) return false;

  return $data;
}
---

Exemplo de login que gera JWT

<?php
// POST /api/login
$data = json_decode(file_get_contents("php://input"), true);

if ($data['email'] !== 'admin@site.com' || $data['password'] !== '123456') {
  http_response_code(401);
  echo json_encode(['error' => 'Credenciais inválidas']);
  exit;
}

$token = generateJWT([
  'id' => 1,
  'email' => $data['email'],
  'role' => 'admin'
], 'SEGREDO_SUPER_SECRETO');

echo json_encode(['token' => $token]);
---

Protegendo rotas com JWT

<?php
$auth = $_SERVER['HTTP_AUTHORIZATION'] ?? '';

if (!preg_match('/Bearer\s+(.*)$/', $auth, $matches)) {
  http_response_code(401);
  exit;
}

$user = validateJWT($matches[1], 'SEGREDO_SUPER_SECRETO');

if (!$user) {
  http_response_code(401);
  exit;
}
---

JWT + CORS (atenção)

Sempre libere o header Authorization:

header("Access-Control-Allow-Headers: Content-Type, Authorization");
---

Boas práticas de segurança com JWT

---

Erros comuns com JWT em PHP

---