GB.
2025-03-115 min read

Understanding CORS in Modern Web APIs

#CORS#Web API#.NET#Security#Frontend

Understanding CORS in Modern Web APIs

If you’ve ever stared at a browser console screaming “No ‘Access-Control-Allow-Origin’ header is present on the requested resource,” you’re not alone. CORS remains one of the most misunderstood topics for developers building modern web applications - especially when working with .NET backends and frontend frameworks.

You probably have a few burning questions right now:

  • Why does my API work perfectly in Postman but fail in the browser?
  • Is CORS the same as domain matching?
  • And if CORS isn’t really security… then what is protecting my API?

Let’s clear up the confusion once and for all with practical examples, real-world explanations, and zero fluff.

Origin vs Domain – The Core Confusion Most Developers Miss

Here’s a question that trips up even experienced developers:

“If the domains are the same, why do I still get a CORS error?”

The answer is simple once you know the definition.

Origin = protocol + domain + port

Domain is not enough for CORS. The browser is extremely strict.

Real Examples That Make It Click

Key takeaway: Even https://eg.com and https://sub.eg.com are completely different origins. The browser treats them as strangers.

Is CORS Actually a Server Feature?

This is the question that confuses almost everyone:

“If I fix CORS on my server, am I done?”

The surprising answer: No.

CORS is not enforced by your server. It is enforced only by the browser.

That’s why:

  • Postman works
  • curl works
  • Backend-to-backend calls work
  • Python scripts work

… but your JavaScript running in the browser gets blocked.

CORS is simply a browser safety mechanism.
Your server can return whatever headers it wants - the browser decides whether to allow the request.

If CORS Isn’t Security, Then What Actually Protects My API?

This is where most developers get it wrong.

You’ve probably asked yourself:
“If anyone can bypass CORS, why even bother with it?”

Exactly. CORS is not a security wall. Attackers can easily call your API using:

  • Postman
  • curl
  • Custom scripts
  • Proxy tools

Real API security comes from completely different layers:

  • Authentication → JWT tokens or OAuth2
  • Authorization → Role-Based Access Control (RBAC)
  • API Gateway → Central place for validation (Ocelot, Kong, Azure API Management)
  • Rate Limiting → Stop brute-force and abuse
  • Input Validation → Block injection attacks

CORS is only there to protect users from certain cross-origin attacks. It does not protect your API.

Preflight Requests (OPTIONS) – The Step Most People Don’t Understand

Here’s another common question developers ask:

“Why is the browser sending an OPTIONS request before my actual PUT/PATCH/DELETE?”

That’s called a preflight request. The browser does it automatically for “non-simple” requests.

When Does a Preflight Happen?

  • Methods: PUT, PATCH, DELETE (and sometimes POST)
  • Custom headers (like Authorization)
  • Content-Type other than application/x-www-form-urlencoded, multipart/form-data, or text/plain (e.g., application/json)

Simple Preflight Flow Example

  1. Preflight (Negotiation)
    Browser sends:
    OPTIONS /api/users/1
    with headers asking:

    • Is PATCH allowed from my origin?
    • Is the Authorization header allowed?
    • Is my content-type allowed?
  2. Server Responds
    If approved, server returns proper Access-Control-Allow-* headers.

  3. Actual Request
    Only then does the browser send the real PATCH /api/users/1 request.

Think of preflight as the browser politely asking for permission before doing anything risky.

Common CORS Misconceptions (That Are Still Costing You Time)

Let’s bust a few myths you might still believe:

  • Myth: “A CORS error means my API is broken.”
    Reality: Your API is usually working fine. The browser is just blocking the response.

  • Myth: “Enabling CORS makes my API secure.”
    Reality: Postman can still hit your API with zero issues.

  • Myth: “If the domains match, I won’t have CORS problems.”
    Reality: Remember the origin table above - protocol and port matter too.

Pro Tips from Real-World Projects

  • Always test your APIs in both the browser and Postman during development.
  • Never use AllowAnyOrigin (or equivalent) in production - always whitelist specific origins.
  • When debugging PUT/PATCH failures, check the preflight OPTIONS response first.
  • In .NET, configure CORS properly in your Program.cs or use an API Gateway like Ocelot for cleaner control.
  • Document your allowed origins clearly in your team’s internal wiki.

Final Summary – What You Should Remember

  • CORS is a browser rule, not server security
  • Origin is much stricter than domain
  • Preflight requests are just the browser negotiating permissions
  • Real protection comes from authentication, authorization, and proper API architecture

Happy coding, and may your CORS headers always be perfectly aligned.

Enjoyed this article? Share it with your network!