Introdução ao OAuth 2.0 e JWT em PHP
\n\nAs aplicações web modernas raramente funcionam sem sistemas de autorização. Os dois protocolos mais populares — OAuth 2.0 e JWT (JSON Web Token) — permitem que desenvolvedores criem soluções seguras e escaláveis. Neste artigo, vamos abordar como implementar a autorização OAuth 2.0 e JWT em PHP do zero. O material é voltado para iniciantes, portanto todos os conceitos serão explicados de forma simples com exemplos práticos.
\n\nOAuth 2.0 é um protocolo de acesso delegado. Ele permite que usuários concedam a terceiros acesso limitado aos seus recursos sem compartilhar a senha. JWT, por sua vez, é um formato compacto de token que contém todas as informações necessárias sobre o usuário e seus direitos.
\n\nO que é JWT e como funciona?
\n\nJWT (JSON Web Token) é um padrão aberto (RFC 7519) que define uma forma compacta e autossuficiente de transmitir informações entre partes como um objeto JSON. O token consiste em três partes separadas por pontos:
\n\n- \n
- Header — contém informações sobre o tipo de token e o algoritmo de criptografia (geralmente HS256 ou RS256). \n
- Payload — contém as "declarações" (claims): dados do usuário, hora de emissão (iat), hora de expiração (exp) e outros. \n
- Signature — assinatura criada com base no header, payload e chave secreta. Garante a integridade dos dados. \n
Aqui está como é um JWT típico:
\n\neyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6ItCQ0L3QsNGC0L7Qu9C40LkiLCJpYXQiOjE1MTYyMzkwMjJ9.4vGJ7qF6b0Q9l8z3X5p2Rk1h7t9y2w4z6x8c0v2b4n6m8\n\nA vantagem do JWT é que o servidor não precisa armazenar sessões no banco de dados — todas as informações já estão codificadas no token. Isso torna o sistema facilmente escalável.
\n\nInstalação da biblioteca para trabalhar com JWT em PHP
\n\nPara trabalhar com JWT em PHP, usaremos a biblioteca popular firebase/php-jwt. Instale-a via Composer:
composer require firebase/php-jwt\n\nCriação e verificação de token JWT
\n\nVamos considerar um exemplo básico de criação de token no login do usuário e sua verificação ao acessar um recurso protegido.
\n\n1. Geração do token (login.php):
\n\n<?php\nrequire_once 'vendor/autoload.php';\n\nuse Firebase\\JWT\\JWT;\nuse Firebase\\JWT\\Key;\n\n$secretKey = 'sua-chave-secreta-com-pelo-menos-32-caracteres';\n\n// Dados do usuário após autenticação bem-sucedida\n$payload = [\n 'iss' => 'pythonlib.ru', // Emissor do token\n 'sub' => $userId, // ID do usuário\n 'name' => $userName, // Nome do usuário\n 'role' => 'user', // Papel\n 'iat' => time(), // Hora de emissão\n 'exp' => time() + 3600 // Token expira em 1 hora\n];\n\n$jwt = JWT::encode($payload, $secretKey, 'HS256');\n\n// Envia o token para o cliente\necho json_encode(['token' => $jwt]);\n?>\n\n2. Verificação do token (profile.php):
\n\n<?php\nrequire_once 'vendor/autoload.php';\n\nuse Firebase\\JWT\\JWT;\nuse Firebase\\JWT\\Key;\n\n$secretKey = 'sua-chave-secreta-com-pelo-menos-32-caracteres';\n\n// Obtém o token do cabeçalho Authorization\n$headers = getallheaders();\n$authHeader = $headers['Authorization'] ?? '';\n\nif (preg_match('/Bearer\\s(\\S+)/', $authHeader, $matches)) {\n $jwt = $matches[1];\n \n try {\n $decoded = JWT::decode($jwt, new Key($secretKey, 'HS256'));\n \n // Token válido, obtém dados do usuário\n $userId = $decoded->sub;\n $userName = $decoded->name;\n \n // Retorna dados protegidos\n echo json_encode(['status' => 'success', 'user' => $decoded]);\n \n } catch (Exception $e) {\n // Token inválido ou expirado\n htt