Access to fetch at * from origin * has been blocked by CORS policy, even though CORS policy explicitly allows it - express

I am performing a graphql query from my client to my server and am getting the following error in the browser:
Access to fetch at 'https://my-server.com/graphql' from origin 'https://my-client.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.
If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
I once got this same error in the past which is why I added the following to the express middleware on the server which solved it:
const app = express();
app.use(cors({
origin: ['http://localhost:3000', 'https://studio.apollographql.com', "https://my-client.com"],
credentials: true
}))
However without any changes that I can reasonably trace back to this issue the error is occurring again. The strange thing if I run the client and server on my local machine (on localhost:3000 and localhost:4000 respectively) the error does not happen.
Edit:
On the client I use a library called GraphQL Code Generator to generate hooks which execute the relevant queries. One of them is for instance this one:
export function useUsersQuery(baseOptions?: Apollo.QueryHookOptions<UsersQuery, UsersQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<UsersQuery, UsersQueryVariables>(UsersDocument, options);
}
And to execute the query: const { data, loading, error } = useUsersQuery()
I am using the following package versions
apollo-server-express#3.11.1
express#4.18.2
cors#2.8.5

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

api request has been blocked by CORS policy

In my next.js project I'm trying to send a POST request using axios:
axios.defaults.baseURL = "https://{my-server-url}/api";
useEffect(() => {
axios({
method: "POST",
url: "/build_pages",
data: {
page_id: 3,
},
}).then((res) => {
console.log(res.data);
});
}, []);
I'm getting the following CORS error:
My server is [laravel] php and is deployed on cpanel, but before I deployed my backend to cpanel (i.e. when I was working on localhost) I did not get this error.
How do I turn off this error (note that I don't want to download any web browser extension to fix the CORS error)
I came across this link but it does not say where (which file) to add it to so I'm stuck
Edit: I tried the middleware solution provided in this answer: https://stackoverflow.com/a/69151121/12009071 but also it didn't work, howerver the error changed to:
Access to XMLHttpRequest at 'https://{my-server-url}/api/check_admin_login' from origin 'https://{my-server-url}.vercel.app' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
This is an API-side error. You have to allow cross origin requests on the API server. Based on your question, I assume your API is NOT the Next.js project.
Therefore, you should check the settings of your server. The next.js POST call is not the issue.

If I get a cross-origin-request-blocked error on my front-end, why does the request still seem to get processed

I was under the impression that cross-origin requests getting blocked was primarily a security thing that prevents evil websites from getting or updating information on your web service.
I've noticed however that even though a request gets blocked on my front-end, the code still executes in the backend.
For example:
import express = require('express')
const app = express()
const port = 80
app.use(function (req, res, next) {
// res.header("Access-Control-Allow-Origin", "*")
// res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept")
next()
});
app.get('/foo', (req, res) => {
console.log("test1")
res.json({
data: "Hello"
})
console.log("test2")
})
app.listen(port, () => {
console.log(`app listening at http://localhost:${port}`)
})
If my frontend then makes a request the express service, the request will fail because of cross-origin but the express service will still log
test1
test2
Should express block the service from continuing to run since the origin is not permitted? Isn't a security threat if the express code still executes even if the front-end gets an error?
There are two types of CORs requests in the browser implementation and which is used depends on the specific request being made.
For requests that do not require pre-flight, the request is made to the back-end and then the browser examines the resulting headers to see if the CORs request is permitted or not. If it's not permitted (as in the case you show), then the result of the request is blocked from the client so it can't see the result of the request (even though the server fully processed it).
As best I can tell from what you show, everything here is working as expected. The request is considered a "simple request" and does not require preflight. Browser-based Javascript will not be allowed to get results from this route if it's not the same origin.
For requests that do require preflight (there's a list of things in a request that can trigger preflight), then the browser will first ask the server if the request is permitted by sending an OPTIONS request to the same route. The server then decides whether to allow the request or not. If the browser gets permission from the server, then it sends the real request.
You can see what triggers preflight here.
Presumably, the browser doesn't use preflight all the time because it's less efficient (requiring double the requests).

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.

No 'Access-Control-Allow-Origin' header when launch ajax in vue component under electron-vue dev envrironment

Following https://github.com/SimulatedGREG/electron-vue, i run yarn run dev and make a minor change to see how it works.
In electron vue application, i have launch an ajax request in vue component created hook function,
created: function () {
let self = this
this.$http.get('http://example.com/api/hwid/383').then(
function (resp) {
self.title = resp.title
}
)
}
In the vue-electron dev tool, there are following error in the console:
XMLHttpRequest cannot load http://example.com/api/hwid/383. No 'Access- Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9080' is therefore not allowed access.
How to solve that?
Must i set the cross domain in the server side?
Yes, you should add Access-Control-Allow-Origin for localhost on the server side.
Since it's only a browser policy, you eventually can write your own (proxy) server which will get http://example.com/api/hwid/383 data. Then you will request data through your server without any issues.