Nginx · The edge of your stack
How do you handle CORS in Nginx?
Short answer
Return Access-Control-Allow-Origin and related headers for allowed origins, answer OPTIONS preflight requests, and never combine a wildcard origin with credentials. CORS is enforced by browsers, not a server authorization mechanism.
A browser blocks a cross-origin response unless the server opts in with CORS headers. For non-simple requests it first sends an OPTIONS preflight, which Nginx can answer directly instead of forwarding to the backend.
map $http_origin $cors_origin {
default "";
"https://app.example.com" $http_origin;
}
server {
location /api/ {
add_header Access-Control-Allow-Origin $cors_origin 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-Allow-Credentials "true" always;
add_header Vary "Origin" always;
if ($request_method = OPTIONS) {
return 204;
}
proxy_pass http://backend;
}
}Rules that prevent breakage
- The allow-origin value must match the requesting origin exactly, or be a wildcard without credentials
- Credentials require a specific origin and Access-Control-Allow-Credentials: true
- Preflight needs allowed methods and allowed request headers
- Vary: Origin keeps caches from serving one origin's response to another
- CORS does not protect an API from non-browser clients; keep authentication and authorization server-side
Follow-ups you should expect
Interviewers use these to check whether the first answer was understanding or memorisation.
- 1Why can't Access-Control-Allow-Origin be a wildcard with credentials?
- 2What headers does a preflight request need?
- 3Why is Vary: Origin important when caching?
- 4Does CORS prevent curl or server-to-server access?
Say it in the interview
I handle CORS with an allowlist map from Origin to the value to return, plus methods, headers, credentials and Vary: Origin. I answer OPTIONS preflight requests directly with 204. I never combine a wildcard origin with credentials or echo arbitrary origins. I also make clear that CORS is a browser control, not a substitute for server-side authentication.
Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.
Related questions
Reading is step one
Now say it out loud.
Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live Nginx mock interview and get scored feedback on depth, clarity and confidence.