fruitcake/php-cors
Standalone PHP CORS library and Symfony HttpFoundation middleware implementing the W3C CORS spec. Configure allowed origins, methods, headers, exposed headers, and max-age; supports regex origin patterns. Used by Stack and Laravel integrations.
Install via Composer: composer require fruitcake/php-cors. This package provides the core CorsService — a standalone, standards-compliant CORS handler — but does not include a pre-built middleware. In Laravel, start by creating a custom CORS middleware (e.g., CorsMiddleware) that uses CorsService to handle CORS logic. Review the constructor options (allowedOrigins, allowedMethods, supportsCredentials, etc.) in the README — configuration is entirely programmatic. For most day-one use cases, define static CORS rules in your middleware class or config, then wire it into app/Http/Kernel.php early in the middleware stack (e.g., above Authenticate or SubstituteBindings).
Minimal Laravel Middleware: Inject CorsService with config, detect CORS requests using isCorsRequest(), handle preflight via handlePreflightRequest() (which returns a Response), and augment actual requests with addActualRequestHeaders(). Keep the logic isolated to one middleware class.
Dynamic per-group routing: Define multiple CORS configurations (e.g., 'public' => [...], 'secure' => [...]) and route-based selection using middleware parameters (->middleware('cors:api')). Example: /api/public/* allows open origins; /api/admin/* restricts to internal services and enables credentials.
Wildcard & pattern safety: Prefer allowedOriginsPatterns for dynamic domains (e.g., /^https:\/\/[a-z0-9-]+\.myapp\.com$/) over allowedOrigins with *, especially when supportsCredentials => true. Use ['*'] only for non-credential endpoints (e.g., public static assets), as browsers block credentials + wildcard combinations.
Framework-agnostic reuse: For non-Laravel Symfony apps or microframeworks (e.g., Slim, Lumen), use CorsService directly in custom middleware or HTTP kernel decorators — no framework coupling required.
Middleware ordering is critical: Place CORS middleware before routing/auth logic. If a 404/401 is returned early, the preflight (OPTIONS) response won’t include CORS headers, causing browser failures.
Case-sensitivity traps: While allowedMethods and allowedHeaders are internally case-insensitive, the Access-Control-Allow-Headers in the preflight response must match the exact casing of the client’s Access-Control-Request-Headers. Normalize your config to camelCase (e.g., ['x-requested-with']) and verify request headers via logging if CORS fails silently.
Credentials + wildcards are forbidden by browsers: Even if CorsService enforces this internally (e.g., throws if ['*'] + supportsCredentials), your custom middleware might inadvertently override headers (e.g., setHeader('Access-Control-Allow-Origin', '*')). Audit any manual header additions in custom code.
Vary header and caching: CorsService auto-adds Vary: Origin, Access-Control-Request-Method, and Access-Control-Request-Headers. Ensure your reverse proxy (Nginx, Cloudflare) respects these — otherwise, caches may serve wrong CORS headers (e.g., Origin: A’s response cached for Origin: B). Use Cache-Control: no-store on CORS responses in high-security contexts.
Testing preflight reliably: Use curl -X OPTIONS -H "Origin: https://example.com" -H "Access-Control-Request-Method: POST" http://your-api/endpoint to simulate preflight requests. Verify headers like Access-Control-Allow-Origin, Access-Control-Allow-Methods, and Access-Control-Max-Age are present and correct.
How can I help you explore Laravel packages today?