1

I have a .NET6 minimal api deployed in Heroku that is returning this following CORS error:

Access to XMLHttpRequest at '...' from origin '...' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

But the same configuration is not returning any errors when I run my app locally.

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddCors(options =>
{
    options.AddPolicy("MyAllowedOrigins",
        policy =>
        {
            policy
                .AllowAnyOrigin()
                .AllowAnyMethod()
                .AllowAnyHeader();
        });
});
var app = builder.Build();

app.UseSwagger();
app.UseSwaggerUI();

app.UseHttpsRedirection();

app.UseCors("MyAllowedOrigins");

app.MapPost("/upload-file", async ([FromServices] IWordService service, HttpRequest request) =>...
Guru Stron
  • 102,774
  • 10
  • 95
  • 132
lcarvalho
  • 71
  • 1
  • 4
  • Try to restart your heroku dyno, your code should work. – IamK Oct 01 '22 at 22:54
  • I restarted it but I'm getting the same error. Maybe it is the order that I added the CORS? – lcarvalho Oct 02 '22 at 10:07
  • i've tried that on my machine, and it works in every combination – IamK Oct 02 '22 at 10:11
  • What is the output of `curl -H "Origin: https://example.com" --verbose \ https://example.com` – IamK Oct 02 '22 at 10:19
  • Trying 54.159.116.102:443... Connected to exam-grader-api.herokuapp.com (54.159.116.102) port 443 (#0) schannel: disabled automatic use of client certificate ALPN: offers http/1.1 ALPN: server did not agree on a protocol. Uses default. GET /get-students?level=PET&year= HTTP/1.1 Host: exam-grader-api.herokuapp.com User-Agent: curl/7.83.1 Accept: */* Origin: https://exam-grader-web.herokuapp.com/ Mark bundle as not supporting multiuse HTTP/1.1 500 Internal Server Error Connection: keep-alive Content-Length: 0 Date: Sun, 02 Oct 2022 10:46:20 GMT Server: Kestrel Via: 1.1 vegur – lcarvalho Oct 02 '22 at 10:47

2 Answers2

0

WARNING: You should not do this. It is not a safe way. Do it only if you don't care.

The following is middleware for Minimal API. It effectively bypasses CORS by giving him what he wants:

//f**k you CORS
app.Use(async (context, next) =>
{
    if (context.Request.Method == "OPTIONS")
    {
        context.Response.StatusCode = 200;

        await WriteCorsAsync(context);

        await context.Response.WriteAsync("");
    }
    else
    {
        context.Response.OnStarting(WriteCorsAsync, context);

        await next(context);
    }

    static Task WriteCorsAsync(object state)
    {
        var context = (HttpContext)state;

        context.Response.Headers.Add("Access-Control-Allow-Origin", context.Request.Headers.Origin);
        context.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
        context.Response.Headers.Add("Access-Control-Allow-Methods", string.Join(", ", new[] { context.Request.Method }.Union(context.Request.Headers.AccessControlRequestMethod.Select(v => v))));
        context.Response.Headers.Add("Access-Control-Allow-Headers", string.Join(", ", context.Request.Headers.Select(p => p.Key).Union(context.Request.Headers.AccessControlRequestHeaders.Select(v => v))));

        return Task.CompletedTask;
    }
});
user1576055
  • 567
  • 1
  • 4
  • 16