diff --git a/src/Application.php b/src/Application.php index 249847f5..5c911b1b 100644 --- a/src/Application.php +++ b/src/Application.php @@ -2,6 +2,7 @@ namespace App; +use App\Http\Middleware\CorsMiddleware; use App\Http\Middleware\DemoRateLimitMiddleware; use App\Http\Middleware\MissingControllerMiddleware; use App\Http\Middleware\RedirectMiddleware; @@ -85,6 +86,9 @@ public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue { // Handle cached files ->add(CacheMiddleware::class) + // CORS headers for API access from documentation sites + ->add(CorsMiddleware::class) + ->add(RedirectMiddleware::class) // Apply routing diff --git a/src/Http/Middleware/CorsMiddleware.php b/src/Http/Middleware/CorsMiddleware.php new file mode 100644 index 00000000..dc1608a6 --- /dev/null +++ b/src/Http/Middleware/CorsMiddleware.php @@ -0,0 +1,60 @@ + + */ + protected array $allowedOrigins = [ + 'https://php-collective.github.io', + 'https://sandbox.dereuromark.de', + ]; + + /** + * Process the request and add CORS headers if origin is allowed. + * + * @param \Psr\Http\Message\ServerRequestInterface $request The request. + * @param \Psr\Http\Server\RequestHandlerInterface $handler The request handler. + * @return \Psr\Http\Message\ResponseInterface A response. + */ + public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface { + $origin = $request->getHeaderLine('Origin'); + + // Handle preflight OPTIONS requests + if ($request->getMethod() === 'OPTIONS') { + $response = new Response(); + $response = $response->withStatus(204); + } else { + $response = $handler->handle($request); + } + + // Only add CORS headers if origin is in allowlist + if ($origin !== '' && in_array($origin, $this->allowedOrigins, true)) { + $response = $response + ->withHeader('Access-Control-Allow-Origin', $origin) + ->withHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS') + ->withHeader('Access-Control-Allow-Headers', 'Content-Type, X-Requested-With') + ->withHeader('Access-Control-Max-Age', '86400'); + } + + return $response; + } + +}