Installation:
composer require nelmio/cors-bundle
config/bundles.php:
Nelmio\CorsBundle\NelmioCorsBundle::class => ['all' => true],
Basic Configuration:
config/packages/nelmio_cors.yaml:
nelmio_cors:
paths:
'^/api/*':
allow_origin: ['*']
allow_methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS']
allow_headers: ['Content-Type', 'Authorization']
expose_headers: ['Link']
max_age: 3600
First Use Case:
/api/test). Use browser DevTools (Network tab) or curl -I to verify headers like:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS
API-Only CORS:
/api/*) while excluding frontend assets:
paths:
'^/api/*': { allow_origin: ['*'] }
'^/assets/*': ~ # Explicitly disable CORS for static files
Dynamic Origin Whitelisting:
allow_origin: ['%env(CORS_ALLOW_ORIGIN)%']).paths:
'^/user/*':
allow_origin: ['%kernel.environment%']
allow_origin_resolver: ~ # Custom resolver class
Preflight Handling:
OPTIONS requests. For custom logic, create an event subscriber:
use Nelmio\CorsBundle\Event\PreflightEvent;
public function onPreflight(PreflightEvent $event) {
$event->setAllowedMethods(['GET', 'POST']);
}
Symfony Messenger Integration:
/_symfony_messenger):
paths:
'^/_symfony_messenger': { allow_origin: ['*'] }
Static File Handling:
/build/*), configure CORS at the web server level (Nginx/Apache) or use a middleware:
// src/Kernel.php
$kernel->add(new Nelmio\CorsBundle\Middleware\CorsMiddleware($this));
imports to split configs (e.g., dev.yaml, prod.yaml):
imports:
- { resource: nelmio_cors.yaml }
- { resource: nelmio_cors.dev.yaml }
nelmio_cors.event_listener or nelmio_cors.event_subscriber in services.yaml.nelmio_cors.tester to assert CORS headers in PHPUnit:
$this->assertCorsHeaders(['Access-Control-Allow-Origin' => '*']);
Static Files:
/build/js/app.js). These must be configured in your web server..htaccess (Apache) or Nginx add_header directives:
location /build/ {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET';
}
Path Matching:
'^/api/v1/*' vs '^/api/*').^ and $ anchors for precision:
paths:
'^https://example.com/api/*': { ... } # Full URL matching
Caching Headers:
max_age in CORS preflight responses can cause stale caches if origins change.max_age: 0 in development or use short TTLs (e.g., 300).Symfony Flex Conflicts:
bundles.php if using Flex (v4.1+).Event Order:
tags:
- { name: kernel.event_subscriber, priority: 255 } # Highest priority
curl -I http://example.com/api/test or browser DevTools.Nelmio\CorsBundle\Event\CorsEvent:
monolog:
handlers:
cors:
type: stream
path: "%kernel.log_dir%/cors.log"
channels: ["cors"]
php bin/console debug:config nelmio_cors
Custom Resolvers:
Nelmio\CorsBundle\Resolver\OriginResolverInterface for dynamic origins (e.g., JWT-based):
class AuthOriginResolver implements OriginResolverInterface {
public function resolve(array $config, ServerRequestInterface $request): array {
return ['https://trusted-domain.com'];
}
}
services.yaml:
Nelmio\CorsBundle\Resolver\OriginResolverInterface: '@App\Resolver\AuthOriginResolver'
Middleware Override:
Kernel.php:
$kernel->add(new App\Middleware\CustomCorsMiddleware());
Event Subscribers:
nelmio_cors.preflight or nelmio_cors.response:
use Nelmio\CorsBundle\Event\PreflightEvent;
public static function getSubscribedEvents() {
return [
PreflightEvent::class => 'onPreflight',
];
}
Environment-Specific Configs:
# config/packages/nelmio_cors.dev.yaml
nelmio_cors:
paths:
'^/api/*': { allow_origin: ['http://localhost:3000'] }
How can I help you explore Laravel packages today?