Nginx CORS Headers Configuration
Configure Cross-Origin Resource Sharing (CORS) headers in Nginx to properly handle preflight OPTIONS requests, allowed origins, methods, and credentials.
Detailed Explanation
CORS (Cross-Origin Resource Sharing) is a browser security mechanism that controls which external domains can make requests to your server. Configuring CORS headers in Nginx keeps this cross-cutting concern out of your application code.
Basic CORS Configuration
Add the appropriate response headers to allow cross-origin requests from a specific trusted domain:
location /api/ {
add_header Access-Control-Allow-Origin "https://app.example.com" always;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
add_header Access-Control-Allow-Headers "Authorization, Content-Type" always;
add_header Access-Control-Max-Age 86400 always;
if ($request_method = OPTIONS) {
return 204;
}
proxy_pass http://backend;
}
Handling Preflight Requests
Browsers send an OPTIONS preflight request before making cross-origin requests that include custom headers or non-simple HTTP methods. Nginx should respond to these preflight requests with a 204 No Content status and all required CORS headers. The Access-Control-Max-Age header tells browsers to cache the preflight result for the specified number of seconds, reducing the number of preflight round-trips.
Dynamic Origin Matching
To allow multiple specific origins without resorting to an insecure wildcard, use a map block to conditionally set the header:
map $http_origin $cors_origin {
default "";
"https://app.example.com" $http_origin;
"https://staging.example.com" $http_origin;
}
location /api/ {
add_header Access-Control-Allow-Origin $cors_origin always;
}
Credentials and Cookies
If your API requires cookies or authentication headers to be sent with cross-origin requests, you must add the credentials header:
add_header Access-Control-Allow-Credentials "true" always;
When Allow-Credentials is set to true, the Allow-Origin header cannot use a wildcard (*). You must specify the exact origin domain. This is a strict browser enforcement rule that cannot be bypassed.
The always Parameter
Adding always to each add_header directive ensures the CORS header is included in all response codes, including 4xx and 5xx error responses. Without always, Nginx only adds headers to successful responses, which causes confusing and hard-to-debug CORS errors when your backend returns an error status.
Security Warning
Avoid using Access-Control-Allow-Origin: * for APIs that handle sensitive or authenticated data. Always restrict the allowed origin to known, trusted domains to prevent unauthorized cross-origin data access.
Use Case
Your frontend application is hosted on a different domain than your API server, and browsers are blocking API requests due to the same-origin policy.