CORS in ASP.NET Core: It’s More Than Just Fixing a Browser Error

I’ll admit something.

For a long time, whenever I saw this error:

“Access to fetch at ‘https://api.example.com‘ from origin ‘https://localhost:3000‘ has been blocked by CORS policy.”

My first reaction was simple:

“Let me add AllowAnyOrigin() and move on.”

The application worked.

The error disappeared.

Problem solved… or so I thought.

Later, I decided to understand what CORS was actually doing.

And I realized something important:

CORS isn’t a server feature. It’s a browser security feature.

Your API might happily return a response.

But the browser blocks JavaScript from accessing it if the request violates the server’s CORS policy.

That’s why Postman works while the browser fails.


What Is CORS?

CORS (Cross-Origin Resource Sharing) is a mechanism that allows a server to specify which origins can access its resources.

An origin consists of:

  • Protocol (https)
  • Domain (example.com)
  • Port (5001)

If any of these differ, the browser considers it a different origin.

For example:

https://localhost:3000

and

https://localhost:5001

are different origins.


Configuring CORS in ASP.NET Core

Register a policy:

builder.Services.AddCors(options =>
{
    options.AddPolicy("FrontendPolicy", policy =>
    {
        policy.WithOrigins("https://localhost:3000")
              .AllowAnyHeader()
              .AllowAnyMethod();
    });
});

Apply the policy:

app.UseCors("FrontendPolicy");

Avoid This in Production

.AllowAnyOrigin()

While it’s convenient during development, allowing every origin in production can expose your API unnecessarily.

Instead, explicitly specify the trusted origins your application should allow.


Middleware Order Matters

A common mistake is placing UseCors() in the wrong position.

A typical pipeline looks like this:

app.UseRouting();

app.UseCors("FrontendPolicy");

app.UseAuthentication();

app.UseAuthorization();

app.MapControllers();

If CORS isn’t applied at the correct point in the pipeline, the browser may still block requests.


Final Thoughts

Today, I don’t configure CORS just to remove an error message.

I configure it knowing why the browser enforces it and how it protects users.

Understanding the reason behind a feature is far more valuable than memorizing the code to make an error disappear.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *