Apache CORS Configuration — Adding Cross-Origin Headers with mod_headers
In this tutorial, you will learn about Apache CORS Configuration. We cover key concepts, practical examples, and best practices to help you master this topic.
Apache HTTP Server provides CORS header injection through mod_headers, with preflight handling via mod_rewrite and dynamic origin validation using SetEnvIf directives.
What You'll Learn
- Enabling mod_headers for CORS in Apache
- Writing Header directives for Access-Control-* headers
- Handling OPTIONS preflight with mod_rewrite
Why It Matters
Apache still powers many shared hosting and enterprise environments. CORS configuration at the Apache layer allows centralized policy management without application changes. DodaTech's legacy partner portal uses Apache with mod_headers for CORS.
flowchart LR
A["Apache HTTPD"] --> B{"Request"}
B --> C["mod_rewrite checks method"]
C -->|"OPTIONS"| D["Return 200 with CORS headers"]
C -->|"Other"| E["mod_headers adds CORS headers"]
E --> F["Proxy or serve static files"]
D --> G["Response to browser"]
F --> G
Code Examples
# Basic Apache CORS configuration in .htaccess or httpd.conf
<IfModule mod_headers.c>
# Allow specific origin
Header set Access-Control-Allow-Origin "https://app.example.com"
# Allow credentials
Header set Access-Control-Allow-Credentials "true"
# Expose custom headers
Header set Access-Control-Expose-Headers "X-RateLimit-Remaining, X-Request-ID"
# Handle preflight request
SetEnvIf Request_Method OPTIONS $cors_preflight=1
Header set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" env=cors_preflight
Header set Access-Control-Allow-Headers "Content-Type, Authorization" env=cors_preflight
Header set Access-Control-Max-Age "86400" env=cors_preflight
Header set Content-Type "text/plain" env=cors_preflight
# Return 204 for preflight
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=204,L]
</IfModule>
# Dynamic CORS with SetEnvIf
SetEnvIf Origin "^(https://app\.example\.com)$" ALLOWED_ORIGIN=$1
SetEnvIf Origin "^(https://admin\.example\.com)$" ALLOWED_ORIGIN=$1
SetEnvIf Origin "^(https://dashboard\.example\.com)$" ALLOWED_ORIGIN=$1
Header set Access-Control-Allow-Origin "%{ALLOWED_ORIGIN}e" env=ALLOWED_ORIGIN
Header set Access-Control-Allow-Credentials "true" env=ALLOWED_ORIGIN
<If "env('ALLOWED_ORIGIN') == '' && req('Origin') != ''">
Header set Access-Control-Allow-Origin "null"
</If>
# .htaccess example for shared hosting
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=204,L]
</IfModule>
<IfModule mod_headers.c>
Header always set Access-Control-Allow-Origin "https://app.example.com"
Header always set Access-Control-Allow-Credentials "true"
Header always set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
Header always set Access-Control-Allow-Headers "Content-Type, Authorization"
Header always set Access-Control-Expose-Headers "X-Request-ID"
Header always set Access-Control-Max-Age "3600"
</IfModule>
# Test Apache CORS configuration
curl -I -H "Origin: https://app.example.com" \
https://api.example.com/api/data | grep -i "access-control"
# Test preflight
curl -X OPTIONS -I \
-H "Origin: https://app.example.com" \
https://api.example.com/api/data | grep -i "access-control"
Common Mistakes
1. Using Header Set Without the Always Parameter
Header set applies only to success responses. Use Header always set to apply to all responses.
2. Not Enabling mod_headers and mod_rewrite
These modules must be enabled in Apache configuration for CORS directives to work.
3. Blocked by Apache's AllowOverride
If AllowOverride is not set to All, .htaccess CORS directives may be ignored.
4. Incorrect SetEnvIf Syntax
SetEnvIf patterns use regex syntax. Test patterns carefully to avoid blocking valid origins.
5. Not Handling OPTIONS Method Correctly
Without the RewriteRule for OPTIONS, preflight requests proceed to the application and may fail.
Practice Questions
- What Apache module is required for CORS headers?
- How do you apply CORS headers to all responses including errors?
- What directive handles dynamic origin validation in Apache?
- How do you handle OPTIONS preflight in Apache?
- What is the difference between Header set and Header append?
Answers:
- mod_headers.
- Use Header always set instead of Header set.
- SetEnvIf with regex patterns to capture and validate the Origin header.
- Use RewriteRule to return a 204 response for OPTIONS requests.
- Header set replaces any existing header; Header append adds to existing header values.
Challenge: Configure Apache as a reverse proxy for a Node.js API with CORS. Implement dynamic origin validation using SetEnvIf with regex patterns, handle OPTIONS preflight requests, and add logging for CORS rejections using CustomLog with environment variables.
FAQ
Mini Project
Set up Apache as a CORS gateway for a multi-service architecture. Implement dynamic origin whitelisting with SetEnvIf, preflight handling, credential support, and logging. Create a test suite that verifies CORS headers for allowed origins, blocked origins, and OPTIONS requests. Generate a configuration report.
What's Next
Master CORS error handling and debugging techniques, then explore CORS testing with curl and Postman.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro