Introdução ao OAuth 2.0 e JWT em PHP
\nAs aplicações web modernas estão cada vez mais se afastando da autenticação clássica por sessão em favor de soluções mais flexíveis e escaláveis. Dois protocolos-chave — OAuth 2.0 e JWT (JSON Web Tokens) — tornaram-se o padrão de facto para autorização em APIs REST, aplicações móveis e arquitetura de microsserviços. Neste artigo, vamos analisar com exemplos práticos como implementar autorização OAuth 2.0 e JWT em PHP, utilizando bibliotecas modernas e melhores práticas de segurança.
\nVocê aprenderá como configurar um servidor de autorização, emitir e verificar tokens JWT, organizar a emissão de refresh-tokens e proteger seus endpoints de API. Todos os exemplos de código estão prontos para uso em seus projetos.
\n\nFundamentos do protocolo OAuth 2.0
\nOAuth 2.0 é um protocolo de autorização que permite que aplicações obtenham acesso limitado aos recursos do usuário sem transmitir suas credenciais. No contexto de uma aplicação PHP, o OAuth 2.0 é geralmente implementado através da concessão de código de autorização (Authorization Code Grant) ou da concessão de senha (Password Grant) para serviços próprios.
\n\nPapéis principais no OAuth 2.0
\n- \n
- Resource Owner — o usuário que possui os dados \n
- Client — a aplicação que solicita acesso (por exemplo, seu frontend PHP) \n
- Authorization Server — o servidor que emite os tokens \n
- Resource Server — o servidor que fornece os recursos protegidos (sua API) \n
Fluxo de obtenção de token via Authorization Code Grant
\n- \n
- O usuário acessa a página de autorização \n
- Após o login, o usuário é redirecionado de volta à aplicação com um código temporário \n
- O servidor PHP troca o código por access_token e refresh_token \n
- Todas as requisições subsequentes à API são feitas com o cabeçalho
Authorization: Bearer <access_token>\n
Implementação de JWT em PHP com a biblioteca firebase/php-jwt
\nPara trabalhar com JWT em PHP, usaremos a biblioteca popular firebase/php-jwt. Instale-a via Composer:
composer require firebase/php-jwt\n\nGeração de token JWT
\nVamos criar uma função para emitir um access-token com payload (claims):
\n<?php\nuse Firebase\\JWT\\JWT;\nuse Firebase\\JWT\\Key;\n\nfunction generateAccessToken(int $userId, string $email): string {\n $secretKey = 'your-256-bit-secret-key-here';\n $issuedAt = time();\n $expirationTime = $issuedAt + 3600; // 1 hora\n\n $payload = [\n 'iss' => 'pythonlib.ru',\n 'iat' => $issuedAt,\n 'exp' => $expirationTime,\n 'sub' => $userId,\n 'email' => $email,\n 'roles' => ['user']\n ];\n\n return JWT::encode($payload, $secretKey, 'HS256');\n}\n\nVerificação de token JWT
\nValidação da autenticidade do token a cada requisição a um recurso protegido:
\n<?php\nfunction validateAccessToken(string $token): ?object {\n $secretKey = 'your-256-bit-secret-key-here';\n try {\n $decoded = JWT::decode($token, new Key($secretKey, 'HS256'));\n return $decoded;\n } catch (\\Exception $e) {\n // Token expirado, inválido ou assinatura não confere\n return null;\n }\n}\n\nMiddleware para verificação de JWT
\nExemplo de um middleware simples que pode ser usado com qualquer framework:
\n<?php\nfunction authMiddleware(): ?object {\n $headers = getallheaders();\n $authHeader = $headers['Authorization'] ?? '';\n\n if (!preg_match('/Bearer\\s(\\S+)/', $authHeader, $matches)) {\n http_response_code(401);\n echo json_encode(['error' => 'Token não fornecido']);\n exit;\n }\n\n $token = $matches[1];\n $user = validateAccessToken($token);\n\n if (!$user) {\n http_response_code(401);\n