To handle CORS correctly in production, you must protect your API while allowing only trusted domains to access it.
Simply doing app.use(cors()) is NOT safe for real-world apps.
Below is the recommended production approach.
✅ 1. Whitelist Only Trusted Origins
Never allow * in production.
Example:
const whitelist = [
"https://yourfrontend.com",
"https://admin.yourfrontend.com"
];
app.use(
cors({
origin: function (origin, callback) {
if (!origin || whitelist.includes(origin)) {
callback(null, true);
} else {
callback(new Error("Not allowed by CORS"));
}
},
credentials: true, // required for cookies, sessions
})
);
✔ Only approved domains can communicate
✔ Blocks unknown origins
✔ Prevents unauthorized frontends from calling your API
✅ 2. Enable Credentials When Using Cookies / JWT Cookies
If you’re using:
- HttpOnly cookies
- Refresh/Access token cookies
Then you must add:
Backend
credentials: true
Frontend
axios.defaults.withCredentials = true;
✔ Required for secure auth
✔ Allows browser to send cookies to backend
✅ 3. Set Proper Allowed Headers and Methods
app.use(
cors({
origin: whitelist,
methods: ["GET", "POST", "PUT", "PATCH", "DELETE"],
allowedHeaders: ["Content-Type", "Authorization"],
})
);
✔ Prevents unexpected HTTP methods
✔ Limits what headers frontend can send
✅ 4. Handle Preflight OPTIONS Requests Manually
When using:
- PUT
- DELETE
- PATCH
- Custom headers
- Cookies
Browser sends a preflight OPTIONS request.
app.options("*", cors());
✔ Prevents 405 errors
✔ Required for cross-site cookies
✅ 5. Use secure cookie settings (If using cookies)
For authentication, set cookies like this:
res.cookie("token", token, {
httpOnly: true,
secure: true, // HTTPS only
sameSite: "none", // allow cross-site
});
✔ Prevent CSRF
✔ Prevent XSS
✔ Allows cross-domain cookie sharing if needed
✅ 6. Use Environment Variables
Different environments have different CORS needs:
PROD_ORIGIN=https://myapp.com
DEV_ORIGIN=http://localhost:3000
const whitelist = [process.env.PROD_ORIGIN];
if (process.env.NODE_ENV === "development") {
whitelist.push(process.env.DEV_ORIGIN);
}
✔ Keeps production safe
✔ Allows flexible development
🔒 7. Do NOT Use '*' in Production
This is insecure:
app.use(cors({ origin: '*' }));
Why unsafe:
- Allows ANY website to call your API
- Malicious websites can make requests
- Cookies cannot be used (blocked by browser)
- No control over access
🔥 8. CORS + Reverse Proxy (NGINX)
If you use NGINX:
- Handle CORS at NGINX layer
- Faster processing
Example NGINX config:
add_header Access-Control-Allow-Origin https://yourfrontend.com;
add_header Access-Control-Allow-Credentials true;
✔ Better performance
✔ Fine control over headers
🎯 Final Interview Answer (Short Summary)
In production, CORS must be configured with a whitelist of trusted domains, enable credentials if using cookies, restrict allowed methods & headers, correctly handle preflight OPTIONS requests, and secure cookies using
secure,httpOnly, andsameSite.
Never use'*'in production. CORS should always be explicitly controlled.