CORS in APIs: Handling Cross-Origin Requests
API7.ai
June 11, 2025
Introduction
Cross-Origin Resource Sharing (CORS) is a security mechanism that allows web applications to request resources from a different domain securely. As APIs power modern web and mobile applications, handling CORS correctly is crucial for seamless functionality and security.
Why should you care about CORS?
- Prevents unauthorized cross-origin requests, reducing security risks.
- Ensures proper frontend-backend communication (e.g., a React app calling a backend API).
- Misconfigured CORS policies can break applications or expose vulnerabilities.
In this guide, we'll explore how CORS works, best implementation practices, security considerations, and real-world troubleshooting techniques—helping API developers and gateway administrators manage CORS effectively.
What is CORS?
1. Definition and Purpose
The Same-Origin Policy (SOP) restricts web pages from making requests to a different origin (domain, protocol, or port). CORS relaxes these restrictions securely by allowing explicitly permitted cross-origin requests.
Common Use Cases:
- A React app (
https://app.example.com
) accessing an API (https://api.example.com
). - Third-party integrations (e.g., embedding external APIs in a SaaS app).
2. How CORS Works
CORS introduces HTTP headers to control access:
Header | Purpose |
---|---|
Access-Control-Allow-Origin | Specifies which origins can access the resource (* or specific domains). |
Access-Control-Allow-Methods | Lists permitted HTTP methods (GET , POST , etc.). |
Access-Control-Allow-Headers | Defines allowed request headers (Authorization , Content-Type , etc.). |
Access-Control-Expose-Headers | Specifies which response headers can be accessed by the client. |
Access-Control-Allow-Credentials | Determines if credentials (cookies, auth tokens) can be included. |
Browser-Server Interaction Flow:
sequenceDiagram Browser->>Server: OPTIONS Preflight Request Server-->>Browser: Responds with Allowed Methods/Headers Browser->>Server: Actual Request (GET/POST/etc.) Server-->>Browser: Returns Data with CORS Headers
- Simple Requests: (e.g.,
GET
with standard headers) skip preflight. - Preflight Requests (
OPTIONS
): Verify permission before the actual request.
Common CORS Issues and Challenges
Misconfigured CORS can block legitimate requests or expose security risks.
Blocked Requests Due to Missing Headers
Example:
Access to fetch at 'https://api.example.com' from origin 'https://client.com' has been blocked by CORS policy.
Cause: Missing Access-Control-Allow-Origin
in the response.
Credentials & Wildcard (*
) Conflict
Access-Control-Allow-Origin: * // Fails if using cookies/auth tokens
Fix: Explicitly specify allowed domains instead of *
.
Preflight Failures
- Missing
OPTIONS
method support. - Unlisted headers in
Access-Control-Allow-Headers
.
Real-World Data:
- 62% of API-related CORS issues stem from misconfigured preflight handling (source: StackOverflow Dev Survey 2023).
3. Implementing CORS in APIs
3.1 Backend Examples
Node.js (Express):
app.use((req, res, next) => { res.setHeader('Access-Control-Allow-Origin', 'https://client.com'); res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'); res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); res.setHeader('Access-Control-Allow-Credentials', 'true'); next(); });
Python (Flask):
from flask_cors import CORS CORS(app, origins=["https://client.com"], supports_credentials=True)
API Gateway (APISIX Example):
plugins: cors: allow_origins: "https://client.com" allow_methods: "GET,POST,OPTIONS" allow_headers: "content-type,authorization"
3.2 Benefits of Gateway-Level CORS
- Centralized management (avoid code duplication).
- Performance optimization (e.g., caching preflight responses).
Best Practices for CORS in APIs
- Restrict Allowed Origins (avoid
*
in production). - Cache Preflight Responses:
Access-Control-Max-Age: 86400 // 24-hour cache
- Limit Exposed Headers:
Access-Control-Expose-Headers: X-Custom-Header
Critical Security Tip:
- Always validate
Origin
headers server-side to prevent spoofing.
flowchart LR A[Incoming Request] --> B{Origin Valid?} B -->|Yes| C[Process Request] B -->|No| D[Block Request]
Debugging CORS Issues
- Browser DevTools: Check failed requests under the Network tab.
- cURL for Testing:
curl -H "Origin: https://client.com" -I https://api.example.com
- Common Errors & Fixes:
Error | Solution |
---|---|
No 'Access-Control-Allow-Origin' header | Add the header to the server response. |
Preflight missing OPTIONS | Ensure the server handles OPTIONS method. |
Security Considerations
- Overly Permissive CORS → CSRF/data theft risks.
- Avoid:
Access-Control-Allow-Origin: * Access-Control-Allow-Credentials: true // Insecure combo!
- Use CSRF Tokens alongside CORS for sensitive endpoints.
Conclusion
CORS is essential for secure cross-origin API interactions. By:
- Configuring allowed origins strictly.
- Handling preflight correctly.
- Using API gateways for scalability.
Next Steps
Stay tuned for our upcoming column on the API 101, where you'll find the latest updates and insights!
Eager to deepen your knowledge about API gateways? Follow our Linkedin for valuable insights delivered straight to your inbox!
If you have any questions or need further assistance, feel free to contact API7 Experts.