add CORS manager with relative docs
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
namespace Api\Core;
|
||||
|
||||
class CorsManager {
|
||||
private $allowedOrigins;
|
||||
private $allowedMethods;
|
||||
private $allowedHeaders;
|
||||
private $exposedHeaders;
|
||||
private $allowCredentials;
|
||||
private $maxAge;
|
||||
|
||||
public function __construct(array $config = []) {
|
||||
$this->allowedOrigins = $config['allowed_origins'] ?? [];
|
||||
$this->allowedMethods = $config['allowed_methods'] ?? ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'];
|
||||
$this->allowedHeaders = $config['allowed_headers'] ?? ['Content-Type', 'Authorization', 'X-Requested-With'];
|
||||
$this->exposedHeaders = $config['exposed_headers'] ?? ['Content-Length', 'X-JSON-Response-Code'];
|
||||
$this->allowCredentials = $config['allow_credentials'] ?? false;
|
||||
$this->maxAge = $config['max_age'] ?? 86400;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the allowed origin for the current request
|
||||
*/
|
||||
public function getOrigin(): ?string {
|
||||
$origin = $_SERVER['HTTP_ORIGIN'] ?? null;
|
||||
|
||||
if (!$origin) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Check if origin is in allowed list
|
||||
if (in_array('*', $this->allowedOrigins)) {
|
||||
return '*';
|
||||
}
|
||||
|
||||
if (in_array($origin, $this->allowedOrigins)) {
|
||||
return $origin;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current request is a preflight OPTIONS request
|
||||
*/
|
||||
public function isPreflightRequest(): bool {
|
||||
return $_SERVER['REQUEST_METHOD'] === 'OPTIONS';
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply CORS headers to the response
|
||||
*/
|
||||
public function applyHeaders(?string $origin = null): void {
|
||||
if ($origin === null) {
|
||||
$origin = $this->getOrigin();
|
||||
}
|
||||
|
||||
if (!$origin) {
|
||||
// If no valid origin, don't set CORS headers
|
||||
// This ensures blocked origins don't accidentally get access
|
||||
header('Vary: Origin');
|
||||
return;
|
||||
}
|
||||
|
||||
header('Access-Control-Allow-Origin: ' . $origin);
|
||||
header('Access-Control-Allow-Methods: ' . implode(', ', $this->allowedMethods));
|
||||
header('Access-Control-Allow-Headers: ' . implode(', ', $this->allowedHeaders));
|
||||
header('Access-Control-Expose-Headers: ' . implode(', ', $this->exposedHeaders));
|
||||
header('Vary: Origin');
|
||||
|
||||
if ($this->allowCredentials) {
|
||||
header('Access-Control-Allow-Credentials: true');
|
||||
}
|
||||
|
||||
header('Access-Control-Max-Age: ' . $this->maxAge);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle preflight OPTIONS request
|
||||
*/
|
||||
public function handlePreflight(): void {
|
||||
$origin = $this->getOrigin();
|
||||
|
||||
if ($origin) {
|
||||
$this->applyHeaders($origin);
|
||||
http_response_code(204);
|
||||
exit;
|
||||
}
|
||||
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if origin is allowed
|
||||
*/
|
||||
public function isOriginAllowed(?string $origin = null): bool {
|
||||
if ($origin === null) {
|
||||
$origin = $this->getOrigin();
|
||||
}
|
||||
|
||||
if (!$origin) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (in_array('*', $this->allowedOrigins)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return in_array($origin, $this->allowedOrigins);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user