CORS policy blocking POST requests to API - vue.js

I'm trying to deploy an app I created online. The UI is created using vue.js and it's calling a API written in dotnet core. I'm running dotnet core 2.2.
The web project and the API are on different servers and accessible under different domains, the web project is hosted on Netlify if that makes a difference. I managed to set up the CORS policy so that locally everything worked fine. When I access the app on the webserver I receive CORS errors whenever I post data. My GET and DELETE requests work just fine.
Here is my CORS policy
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("Default", builder =>
{
builder.WithOrigins(/* the domain where my web project is hosted */);
builder.AllowAnyMethod();
builder.AllowAnyHeader();
builder.AllowCredentials();
});
});
}
So I'm thinking everything should be fine. AllowCredentials is required because I'm using SignalR which otherwise wouldn't work.
The error message in the dev tools is
POST [my api endpoint] 400 (Bad Request)
Access to XMLHttpRequest at '[my api endpoint]' from origin 'https://xxx.netlify.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
And when I look into the console where my dotnet project is running I see the following error message
Connection id "0HLQNTR19GE1T" bad request data: "Requests with 'Connection: Upgrade' cannot have content in the request body."
Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException: Requests with 'Connection: Upgrade' cannot have content in the request body.
at Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException.Throw(RequestRejectionReason reason)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Http1MessageBody.For(HttpVersion httpVersion, HttpRequestHeaders headers, Http1Connection context)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Http1Connection.CreateMessageBody()
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequestsAsync[TContext](IHttpApplication`1 application)
So far I tried setting the Access-Control-Allow-Origin = "*" Header via the netlify.toml file, using the [EnableCors] attribute on my controller action. I edited my AJAX request (axios) and set withCredentials: true and in general played around with the CORS policy a lot. Unfortunately without luck and I'm running out of ideas.
I'm happy about any suggestions.

Check your nginx.conf file for a line called proxy_set_header and set it to Connection $http_connection

Related

How to stop 'CORS missing allow origin error' when deploying Express application using Serverless Component?

When my React frontend calls my Typescript Express REST API (hosted on API Gateway using Serverless Components), I get the following error:
Access to XMLHttpRequest at 'https://randomId.execute-api.ap-southeast-2.amazonaws.com/userLoginSignup' from origin 'https://www.tueshey.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
My app.ts CORS config is like this (for reference, here's my whole file):
...
const app = express();
// CORS
const allowlist = ['https://www.tueshey.com'];
const options: cors.CorsOptions = {
origin: allowlist,
};
app.use(cors(options));
...
When I inspect the request locally, there is an OPTIONS request that returns first that includes the Allow Access Origin header but not when I deploy it. It is working correctly locally.
you will have to enable CORS on API Gateway as well. When click on the resource endpoint on API Gateway, on actions there is Enable CORS. That will add Options method also for your resource. If you want some customization you will have to add OPTIONS method manually

Manage CORS between Google App Engine & Google Cloud Function

I'm trying to set up a new instance of a simple App Engine which communicate with a backend-function hosted on Google Cloud Function. The App Engine is protected with IAP, and the Google Cloud Function is private only. The GAE use Angular Framework and GCF use Node 14 with Express
.
I can't access to my GCF from the App Engine because the requests are blocked by CORS.
Access to XMLHttpRequest at '' from origin '' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I tried the popular solutions on the web :
Use the cors librairie on the GCF. So I had on my GCF
var cors = require('cors')
app.use(cors(cors({ credentials: true, origin: true })))
And I also add this line for every request
res.set('Access-Control-Allow-Origin', '*')
Add the http-header on my app.yaml
handlers:
- url: /(.*\.[A-Za-z0-9]{1,4})$
static_files: dist/\1
upload: dist/(.*\.[A-Za-z0-9]{1,4})$
http_headers:
Access-Control-Allow-Origin: "*"
- url: /(.*)$
static_files: dist/index.html
upload: dist/index.html
http_headers:
Access-Control-Allow-Origin: "*"
But I still get the same error message.
EDIT : so the first problem was due to an authentication issue, that why the error have the same response. So I decided to deploy the 2 apps on App Engine to simplify communication between the 2 services.
You can now have full access to the HTTP Request/Responses by setting
the appropriate CORS headers as per this documentation.
Just so you know the reason for the error you are facing, it is
because when your web browser is calling a service that is in a
different/cross domain, it doesn’t make a HTTP request right away, it
rather starts with making an OPTIONS request( a preflight request)
and compares the value of Access-Control-Allow-Origin header in the
result with the current domain i.e. it checks for this (req.method
=== 'OPTIONS') in the headers and if the header value matches the host, the actual call is made, otherwise the action is stopped and
the error as the one above is thrown.
To have a thorough understanding of the above concept, have a look at
this stackoverflow answer and read this article for more insights.

Unable to make HTTP post request to .NET Core MVC

I'm currently working on a project where I'm using ASP.NET Core MVC (views are running on another port using Vue). I have set up my models and controller set up and I've tested these using swagger. They work exactly as expected. I have tested the post method on swagger and it works, but requests from my view on another port running Vue and Postman return a 405 error. Inspecting the response headers on Postman, I can see "Allow : DELETE, GET, PUT". Because my view will be running on another port, I've already added CORS the following to my startup configure method (not currently concerned about security implications):
app.UseCors(builder => {
builder.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod();
});
My controller features the following for the POST method:
[ResponseType(typeof (Review))]
[HttpPost]
public async Task Post(Review review)
{
db.Reviews.Add(review);
await db.SaveChangesAsync();
}
I am accessing the URL on Postman from https://localhost:44334/reviews/Post. Reviews being the controller and post is the method. I am not receiving any cross original control errors, just this 405. Why might it be doing this and how can I debug this?
I was trying to post to https://localhost:44334/reviews/Post but my router was not set up like this. Changing the URL to https://localhost:44334/reviews/ and setting the method to Post worked and returned a success 200 response.
It is very common issue. For requests coming from localhost AllowAnyOrigin() doesn't work. You need to allow the origin explicitly like:
services.AddCors(options => options.AddPolicy("ApiCorsPolicy", builder =>
{
builder.WithOrigins("http://localhost:8080").AllowAnyMethod().AllowAnyHeader();
}));
In the configure method tell CORS to use the policy you just created:
app.UseCors("ApiCorsPolicy");
Requests from postman passes the CORS because they attach special headers.

Cannot make cross origin request between local ASP.NET Core MVC services

I have two applications running locally. one is a web service at https://localhost:44365, the other is a web application at https://localhost:44360. The web application needs to access the web service.
The web service is set up with a cors policy that should allow this:
// For running on local pc
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});
...
app.UseCors("CorsPolicy");
app.useMvc();
...
}
When I run both applications and hit the web application in my browser, I get cross origin errors:
Failed to load https://localhost:44365/api/users/current/avatarText: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://localhost:44360' is therefore not allowed access. The response had HTTP status code 500.
The headers in from the service (at 44365) were:
access-control-allow-credentials: true
access-control-allow-headers: content-type
access-control-allow-origin: https://localhost:44360
Oddly, I also show a 500 server error in the method in question. Although when the application (44360) calls it, I am able to step through the method (in 44365) and there is no 500 within that method. I can call it successfully when the call is not cross origin.
You should use AllowAllOrigins
options.AddPolicy("AllowAllOrigins",
builder =>
{
builder.AllowAnyOrigin();
});
Source: https://learn.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-2.1#set-the-allowed-origins
Consider carefully before allowing requests from any origin. Allowing requests from any origin means that any website can make cross-origin requests to your app.
This setting affects preflight requests and the
Access-Control-Allow-Origin header (described later in this topic).

Option request fails with 404

I am trying to send a GET request from my frontend to an API application. Both are running on my local machine. This is how it's built right now:
backend <===> frontend <=x=> API application
All three parts are running independently from each other in their own docker container and are only communicating with each other via HTTP-requests.
As shown in the top image, the connection between backend and frontend works fine, but between frontend and API application does not.
The stack consists of:
frontend: Node server with vue-js and for requests I use axios
API application: Scala with Play Framework 2.5.14
The API application itself works just find when I send a request to her via curl like this:
curl -X GET api-application.docker/api/user?userId=1 \
-H "Authorization: key" -H "Accept: Application/Json"
But when I call it from frontend, I get a 404 on the OPTIONS call. It also gives me a warning in Firefox related to CORS header Access-Control-Allow-Origin:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the
remote resource at http://api-application.docker:9000/api/user?userId=1
(Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
Therefore I first went into the api application's application.conf and added
play.filters.cors {
allowedOrigins = ["*"]
}
I also tried to exchange the asterisk for http://frontend.docker:8080
This didn't work, so I deleted that entry again and added this line instead:
play.filters.disabled += "play.filters.cors.CORSFilter"
Still no change at all. Now I am wondering if I misunderstood the connection between OPTIONS and CORS? Or did I turn it off wrong? Can anyone help me out?
EDIT:
More stuff I tried while waiting for answers, all without success:
I changed the entry in application.conf to:
play.filters.cors {
allowedOrigins = null
}
404 on OPTIONS request indicates your CORSFilter is not enabled. Since you are using Play 2.5 you can enable it by adding
libraryDependencies += filters
to your build.sbt, and by creating the following app/Filters.scala file:
import javax.inject.Inject
import play.api.http.DefaultHttpFilters
import play.filters.cors.CORSFilter
class Filters #Inject() (corsFilter: CORSFilter)
extends DefaultHttpFilters(corsFilter)
By default everything is allowed so there is no need to modify application.conf until you decide to start locking down access. You should NOT add play.filters.disabled += "play.filters.cors.CORSFilter" as this disables CORS support.
The reason why your curl request works fine is because non-browser HTTP clients do not enforce Same-origin policy (see related SO answer), thus CORS does not apply in the case of curl.
404 on OPTIONS request means that the following route is not found:
OPTIONS api-application.docker/api/user
The browser automatically sends this preflight request before sending the corresponding GET request. This OPTIONS route will be automatically taken care of by Play's CORS support once enabled.