180 lines
6.3 KiB
Markdown
180 lines
6.3 KiB
Markdown
# 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:
|
|
|
|
```php
|
|
'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
|
|
|
|
```php
|
|
'cors' => [
|
|
'enabled' => true,
|
|
'allowed_origins' => [
|
|
'http://localhost:3000',
|
|
'http://localhost:8080',
|
|
'http://127.0.0.1:3000',
|
|
],
|
|
'allow_credentials' => false,
|
|
'max_age' => 3600,
|
|
],
|
|
```
|
|
|
|
### Production
|
|
|
|
```php
|
|
'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)
|
|
|
|
```php
|
|
'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:
|
|
|
|
```text
|
|
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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```text
|
|
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
|
|
|
|
1. **Be Specific with Origins**: Always specify exact allowed origins. Don't use `'*'` in production unless absolutely necessary.
|
|
|
|
2. **Credentials**: Only set `allow_credentials: true` if you understand the security implications. This allows cross-origin requests to send cookies.
|
|
|
|
3. **Sensitive Headers**: Don't expose sensitive headers in `exposed_headers`. Only expose what clients actually need.
|
|
|
|
4. **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:
|
|
|
|
```php
|
|
$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 `CorsManager` is 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)
|
|
|
|
## References
|
|
|
|
- [MDN: CORS Documentation](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)
|
|
- [OWASP: CORS](https://owasp.org/www-community/CORS)
|