6.3 KiB
CORS Management Documentation
Overview
This API now includes comprehensive CORS (Cross-Origin Resource Sharing) management. CORS allows your API to be accessed from web applications hosted on different domains.
How It Works
Automatic CORS Header Application
All API responses automatically include CORS headers when CORS is enabled. This allows web applications from configured origins to access your API.
Preflight Request Handling
The API automatically handles preflight OPTIONS requests (sent by browsers before actual requests to CORS-protected resources). These are handled with a 204 No Content response.
Origin Validation
Only requests from configured allowed origins are accepted. Requests from unauthorized origins are rejected.
Configuration
Edit config/config.php to configure CORS:
'cors' => [
'enabled' => true, // Enable/disable CORS
'allowed_origins' => [
'http://localhost:3000',
'https://example.com',
],
'allowed_methods' => ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'],
'allowed_headers' => ['Content-Type', 'Authorization', 'X-Requested-With', 'Accept'],
'exposed_headers' => ['Content-Length', 'X-JSON-Response-Code'],
'allow_credentials' => false,
'max_age' => 86400,
],
Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
enabled |
bool | true |
Enable or disable CORS |
allowed_origins |
array | [] |
List of domains allowed to access the API. Use '*' to allow all (NOT recommended) |
allowed_methods |
array | GET, POST, PUT, DELETE, PATCH, OPTIONS |
HTTP methods allowed |
allowed_headers |
array | Content-Type, Authorization, X-Requested-With, Accept |
Headers allowed in requests |
exposed_headers |
array | Content-Length, X-JSON-Response-Code |
Headers exposed to the client |
allow_credentials |
bool | false |
Allow credentials (cookies, auth) in requests |
max_age |
int | 86400 |
Browser cache time for preflight (seconds) |
Setup for Different Environments
Development
'cors' => [
'enabled' => true,
'allowed_origins' => [
'http://localhost:3000',
'http://localhost:8080',
'http://127.0.0.1:3000',
],
'allow_credentials' => false,
'max_age' => 3600,
],
Production
'cors' => [
'enabled' => true,
'allowed_origins' => [
'https://app.example.com',
'https://admin.example.com',
],
'allow_credentials' => false,
'max_age' => 86400,
],
Allow All Origins (NOT RECOMMENDED for Production)
'cors' => [
'enabled' => true,
'allowed_origins' => ['*'],
'allow_credentials' => false,
],
Browser Preflight Requests
When making cross-origin requests with certain headers or methods (like PUT or DELETE), browsers automatically send a preflight OPTIONS request. The API handles these automatically:
Browser sends: OPTIONS /api/resource
API responds: 204 No Content + CORS headers
Browser sees: Request is allowed, proceeds with actual request
Testing CORS
Using curl
# Test CORS with curl
curl -H "Origin: http://localhost:3000" \
-H "Access-Control-Request-Method: POST" \
-H "Access-Control-Request-Headers: Content-Type" \
-X OPTIONS \
http://localhost:8000/api/users/index -v
Expected Response Headers
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: http://localhost:3000
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With, Accept
Access-Control-Max-Age: 86400
Security Considerations
-
Be Specific with Origins: Always specify exact allowed origins. Don't use
'*'in production unless absolutely necessary. -
Credentials: Only set
allow_credentials: trueif you understand the security implications. This allows cross-origin requests to send cookies. -
Sensitive Headers: Don't expose sensitive headers in
exposed_headers. Only expose what clients actually need. -
HTTPS in Production: Always use HTTPS in production to prevent man-in-the-middle attacks.
CorsManager Class
The CorsManager class handles all CORS logic. You can also use it programmatically:
$corsManager = $container->make(\Api\Core\CorsManager::class);
// Check if current request is allowed
if ($corsManager->isOriginAllowed()) {
// Process request
}
// Apply CORS headers manually
$corsManager->applyHeaders();
// Check for preflight request
if ($corsManager->isPreflightRequest()) {
$corsManager->handlePreflight();
}
Troubleshooting
Preflight request fails
- Check that the origin in the request matches one in
allowed_origins - Verify CORS is enabled in config
- Check browser console for CORS error messages
Missing CORS headers in response
- Ensure CORS is enabled:
'enabled' => true - Verify the requesting origin is in
allowed_origins - Check that
CorsManageris properly initialized in the container
"No Access-Control-Allow-Origin header"
- Browser origin is not in
allowed_origins - Add the origin or use
'*'(only for development)