简体   繁体   中英

Enable preflight CORS between C# and Angular

I am trying to make CORS work for request that require a preflight check. In this case I am making a POST-request to the back-end with an extra header.

Angular:

  let myHeaders = new HttpHeaders();
    myHeaders = myHeaders.append('Content-Type', 'application/json');
    return this.http.post<UserOrder>(`${this.apiURL}/Order/PlaceOrder`, JSON.stringify(payload), {headers : myHeaders});   //email); 

C# API:

[HttpPost("PlaceOrder")]
        public GenericResponse PlaceOrder(UserOrderInsertModel userOrder) 
        {
            return _orderProvider.PlaceOrder(new UserOrder());
        }

Because of the preflight check it first makes an OPTIONS-request. When I do not define a separate options-endpoint in the backend I get a 405 Method Not Allowed. This made me think I needed a separate options-endpoint in my back-end on top of the post-endpoint.

[HttpOptions("PlaceOrder")]
        public ActionResult PlaceOrderOptions(UserOrderInsertModel userOrder)
        {
            return Ok();
        }

After adding this I run into a 415 Unsupported Media Type (on the options call). This is probably because the Content-Type header is not supported for a HttpOptions request.

I feel like the extra options endpoint shouldt be neccessary at all. The CORS-middleware I currently use is as follows:

httpContext.Response.Headers.Add("Access-Control-Allow-Origin", "http://localhost:4200");
httpContext.Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, OPTIONS");  
httpContext.Response.Headers.Add("Access-Control-Allow-Headers", "*");
httpContext.Response.Headers.Add("Access-Control-Allow-Credentials", "true");

Extra info: the CORS in general did already work. Cross-site scripting with a GET request and the Access-Control-Allow-Origin header went well. It is just that I cannot get the POST/OPTIONS combo to work.

Edit: in the Startup.cs I first tried to use app.UseCors() as follows:

app.UseCors();
    options => options.WithOrigins("http://localhost").AllowAnyMethod()
);

This unfortuantely didnt work so then I resorted to inserting the middleware as described above.

Any help would be highly appreciated!

Make sure to call UseCors() before UseEndpoints(). Another hint: If you have credentials, the wildcard do not work as expected. https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods

Ok, thanks a lot everybody. The problem was most likely in the middleware I was using. This was a workaround I added because the UseCors() initially didnt work. This was probably because I didnt use app.AddCors() initially. Without the custom middleware it makes everything a lot easier!

A quick look at the documentation will clarify few things. I share few extracts below

Because of the preflight check it first makes an OPTIONS-request. When I do not define a separate options-endpoint in the backend I get a 405 Method Not Allowed. This made me think I needed a separate options-endpoint in my back-end on top of the post-endpoint.

Preflight Request

For some CORS requests, the browser sends an additional OPTIONS request before making the actual request. This request is called a preflight request.

  • The request method is GET, HEAD, or POST.
  • The app doesn't set request headers other than Accept, Accept-Language, Content-Language, Content-Type, or Last-Event-ID.
  • The Content-Type header, if set, has one of the following values: application/x-www-form-urlencoded multipart/form-data text/plain

I feel like the extra options endpoint shouldt be neccessary at all.

Except you are using CORS with endpoint routing, ASPNET Core should respond to appropriate preflight request when core is enabled on startup.

Condition for Automatic preflight

When the CORS policy is applied either:

  • Globally by calling app.UseCors in Startup.Configure.
  • Using the [EnableCors] attribute.

ASP.NET Core responds to the preflight OPTIONS request.

Enabling CORS on a per-endpoint basis using RequireCors currently does not support automatic preflight requests.

Enable Cors on Starup

In configure service

 public void ConfigureServices(IServiceCollection services)
    {
        .
        //other codes
        .
    services.AddCors(options =>
        {
            options.AddDefaultPolicy(
                builder => //check corsbuilder for additonal config
                {
                    builder.WithOrigins("http://example.com",
                                        "http://www.contoso.com;
                });
        });
        .
        //other codes
        .
    }

and in Configure method

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        .
        //Other codes
        .

        app.UseCors();

        .
        //Other codes
        .
    }

full documentation here for 3.0 https://docs.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-3.0#ecors

Enables Cors and make sure to AllowAnyHeader and AllowAnyMethod Using.Net Core

  services.AddCors(options =>
        {
            options.AddDefaultPolicy(builder =>
                {
                    builder.WithOrigins(Configuration.GetValue<string>("JwtConfig:corsWhiteListUrl"))
                        .AllowAnyHeader()
                        .AllowAnyMethod();
                });
        });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM