feat: implementado middleware de autenticacao jwt conforme especificacao

This commit is contained in:
2026-05-03 22:13:41 -05:00
parent a23785b216
commit d7ed3d7fa5
5 changed files with 149 additions and 7 deletions

View File

@@ -1,7 +1,15 @@
# Usamos a imagem oficial do PHP 8.3
FROM php:8.3-cli
RUN docker-php-ext-install pdo pdo_mysql
# Instalamos o git, unzip (para o Composer) e a extensão do MySQL
RUN apt-get update && apt-get install -y git unzip \
&& docker-php-ext-install pdo pdo_mysql
# Trazemos o Composer pronto da imagem oficial dele
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# Definimos a pasta de trabalho
WORKDIR /var/www/html
# Comando para manter o servidor do Laravel rodando
CMD ["php", "artisan", "serve", "--host=0.0.0.0", "--port=8000"]

View File

@@ -0,0 +1,67 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use Exception;
class JwtAuthMiddleware
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
// 1. Ler Authorization e extrair Bearer <token>
$authHeader = $request->header('Authorization');
if (!$authHeader || !preg_match('/Bearer\s(\S+)/', $authHeader, $matches)) {
return response()->json(['message' => 'Missing or invalid Authorization header'], 401); // Retorna 401 se falhar
}
$token = $matches[1];
// Corrige as quebras de linha da chave pública que vêm do .env
$publicKey = str_replace('\\n', "\n", env('JWT_PUBLIC_KEY_PEM'));
$issuer = env('JWT_ISSUER');
$audience = env('JWT_AUDIENCE');
try {
// 2. Validar assinatura RS256 com JWT_PUBLIC_KEY_PEM e expiração (automático pela biblioteca)
$decoded = JWT::decode($token, new Key($publicKey, 'RS256'));
// 3. Validar iss e aud
if ($decoded->iss !== $issuer) {
throw new Exception('Invalid issuer');
}
$tokenAudience = is_array($decoded->aud) ? $decoded->aud[0] : $decoded->aud;
if ($tokenAudience !== $audience) {
throw new Exception('Invalid audience');
}
// 4. Validar se sub existe (nosso user_id confiável)
if (!isset($decoded->sub) || empty(trim((string)$decoded->sub))) {
throw new Exception('Invalid token claims: sub is missing');
}
// 5. Montar a identificação para as rotas usarem (equivalente ao request.auth = { id: sub, token })
$request->attributes->add([
'auth_id' => $decoded->sub,
'token' => $token
]);
return $next($request);
} catch (Exception $e) {
// Retorna 401 para token inválido ou expirado
return response()->json(['message' => 'Invalid or expired access token'], 401);
}
}
}

View File

@@ -10,8 +10,10 @@ return Application::configure(basePath: dirname(__DIR__))
commands: __DIR__.'/../routes/console.php',
health: '/up',
)
->withMiddleware(function (Middleware $middleware): void {
//
->withMiddleware(function (Middleware $middleware) {
$middleware->alias([
'jwt.auth' => \App\Http\Middleware\JwtAuthMiddleware::class,
]);
})
->withExceptions(function (Exceptions $exceptions): void {
//

View File

@@ -7,6 +7,7 @@
"license": "MIT",
"require": {
"php": "^8.3",
"firebase/php-jwt": "^7.0",
"laravel/framework": "^13.0",
"laravel/tinker": "^3.0"
},

72
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "12a93e9ee58f99b3ee9ac9b5d35d65e5",
"content-hash": "16d1bbc8c7c72342cf2d5a5239006285",
"packages": [
{
"name": "brick/math",
@@ -508,6 +508,70 @@
],
"time": "2025-03-06T22:45:56+00:00"
},
{
"name": "firebase/php-jwt",
"version": "v7.0.5",
"source": {
"type": "git",
"url": "https://github.com/googleapis/php-jwt.git",
"reference": "47ad26bab5e7c70ae8a6f08ed25ff83631121380"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/googleapis/php-jwt/zipball/47ad26bab5e7c70ae8a6f08ed25ff83631121380",
"reference": "47ad26bab5e7c70ae8a6f08ed25ff83631121380",
"shasum": ""
},
"require": {
"php": "^8.0"
},
"require-dev": {
"guzzlehttp/guzzle": "^7.4",
"phpfastcache/phpfastcache": "^9.2",
"phpspec/prophecy-phpunit": "^2.0",
"phpunit/phpunit": "^9.5",
"psr/cache": "^2.0||^3.0",
"psr/http-client": "^1.0",
"psr/http-factory": "^1.0"
},
"suggest": {
"ext-sodium": "Support EdDSA (Ed25519) signatures",
"paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present"
},
"type": "library",
"autoload": {
"psr-4": {
"Firebase\\JWT\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Neuman Vong",
"email": "neuman+pear@twilio.com",
"role": "Developer"
},
{
"name": "Anant Narayanan",
"email": "anant@php.net",
"role": "Developer"
}
],
"description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.",
"homepage": "https://github.com/firebase/php-jwt",
"keywords": [
"jwt",
"php"
],
"support": {
"issues": "https://github.com/googleapis/php-jwt/issues",
"source": "https://github.com/googleapis/php-jwt/tree/v7.0.5"
},
"time": "2026-04-01T20:38:03+00:00"
},
{
"name": "fruitcake/php-cors",
"version": "v1.4.0",
@@ -8369,12 +8433,12 @@
],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"stability-flags": {},
"prefer-stable": true,
"prefer-lowest": false,
"platform": {
"php": "^8.3"
},
"platform-dev": [],
"plugin-api-version": "2.6.0"
"platform-dev": {},
"plugin-api-version": "2.9.0"
}