lthn.io/app/Http/Middleware/IdempotencyKey.php

52 lines
1.3 KiB
PHP
Raw Permalink Normal View History

<?php
declare(strict_types=1);
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
/**
* Idempotency key support for safe POST retries.
*
* If Idempotency-Key header is present, caches the response for 24h.
* Subsequent requests with the same key return the cached response.
*/
class IdempotencyKey
{
public function handle(Request $request, Closure $next): mixed
{
if ($request->method() !== 'POST') {
return $next($request);
}
$key = $request->header('Idempotency-Key');
if (! $key) {
return $next($request);
}
$cacheKey = 'idempotency:' . hash('sha256', $key);
// Return cached response if exists
$cached = Cache::get($cacheKey);
if ($cached) {
return response()->json($cached['body'], $cached['status'])
->header('X-Idempotency-Replayed', 'true');
}
$response = $next($request);
// Cache successful responses for 24h
if ($response->status() < 500) {
Cache::put($cacheKey, [
'body' => json_decode($response->getContent(), true),
'status' => $response->status(),
], 86400);
}
return $response;
}
}