feat: implementado middleware de autenticacao jwt conforme especificacao
This commit is contained in:
10
Dockerfile
10
Dockerfile
@@ -1,7 +1,15 @@
|
|||||||
|
# Usamos a imagem oficial do PHP 8.3
|
||||||
FROM php:8.3-cli
|
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
|
WORKDIR /var/www/html
|
||||||
|
|
||||||
|
# Comando para manter o servidor do Laravel rodando
|
||||||
CMD ["php", "artisan", "serve", "--host=0.0.0.0", "--port=8000"]
|
CMD ["php", "artisan", "serve", "--host=0.0.0.0", "--port=8000"]
|
||||||
67
app/Http/Middleware/JwtAuthMiddleware.php
Normal file
67
app/Http/Middleware/JwtAuthMiddleware.php
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,8 +10,10 @@ return Application::configure(basePath: dirname(__DIR__))
|
|||||||
commands: __DIR__.'/../routes/console.php',
|
commands: __DIR__.'/../routes/console.php',
|
||||||
health: '/up',
|
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 {
|
->withExceptions(function (Exceptions $exceptions): void {
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^8.3",
|
"php": "^8.3",
|
||||||
|
"firebase/php-jwt": "^7.0",
|
||||||
"laravel/framework": "^13.0",
|
"laravel/framework": "^13.0",
|
||||||
"laravel/tinker": "^3.0"
|
"laravel/tinker": "^3.0"
|
||||||
},
|
},
|
||||||
|
|||||||
72
composer.lock
generated
72
composer.lock
generated
@@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "12a93e9ee58f99b3ee9ac9b5d35d65e5",
|
"content-hash": "16d1bbc8c7c72342cf2d5a5239006285",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "brick/math",
|
"name": "brick/math",
|
||||||
@@ -508,6 +508,70 @@
|
|||||||
],
|
],
|
||||||
"time": "2025-03-06T22:45:56+00:00"
|
"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",
|
"name": "fruitcake/php-cors",
|
||||||
"version": "v1.4.0",
|
"version": "v1.4.0",
|
||||||
@@ -8369,12 +8433,12 @@
|
|||||||
],
|
],
|
||||||
"aliases": [],
|
"aliases": [],
|
||||||
"minimum-stability": "stable",
|
"minimum-stability": "stable",
|
||||||
"stability-flags": [],
|
"stability-flags": {},
|
||||||
"prefer-stable": true,
|
"prefer-stable": true,
|
||||||
"prefer-lowest": false,
|
"prefer-lowest": false,
|
||||||
"platform": {
|
"platform": {
|
||||||
"php": "^8.3"
|
"php": "^8.3"
|
||||||
},
|
},
|
||||||
"platform-dev": [],
|
"platform-dev": {},
|
||||||
"plugin-api-version": "2.6.0"
|
"plugin-api-version": "2.9.0"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user