CORS error when calling a Firebase function - reactjs

I am using Google Cloud Functions and I am getting an error related to CORS. I have made a simple function but it's not working because I keep getting the same error over and over again. I have tried almost everything but nothing is working.
Here is the code I am using:
const cors = require('cors')({origin: true});
exports.sample = functions.https.onRequest((req, res) => {
cors(req, res, () => {
res.send('Passed.');
});
});
I have used this and other things too people recommended. I tried adding headers too - but nothing worked.

You should add the header Access-Control-Allow-Origin: * in the response from the Google Cloud Function (GCF).
def cloud_function(request):
response = 'what you expect to return from the GCF'
http_code = 200
headers = {
'Access-Control-Allow-Origin': '*'
}
return response, http_code, headers
Notice the header added on the return from the Cloud Function. If you are forced to return more CORS headers you can add them to the headers variable (or if you want to return other headers for any other reason). For example:
headers = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': '*',
'Access-Control-Allow-Headers': 'Authorization',
'Access-Control-Max-Age': '3600',
'Access-Control-Allow-Credentials': 'true'
}

https://cors-anywhere.herokuapp.com/YOUR-URL.
You can use this proxy to bypass the cors issue if it's not for any production use.
OR
You can use Access-Control-Allow-Origin: * in header while hitting the link.

Related

Problem with CORS on React and PUT Ajax PUT request

I have an issue with my app. I use Express/node for the API and try to access it with React which works fine with Axios.
now I tried a DevExpress grid component to display data. fetching data is working fine but if I want to edit and save I get always a CORS error.
My settings on express:
app.use(
cors({
origin: '*',
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
})
);
The API looks like this:
router.put('/dataToEdit', auth, (req, res) => {
MasterData.updateData(req, res);
});
If I want to call and bind to the grid:
const dataSource = createStore({
key: 'helperboxTypeId',
loadUrl: `${url}/getAlldataToEdit`,
insertUrl: `${url}/dataToEdit`,
updateUrl: `${url}/dataToEdit`,
deleteUrl: `${url}/dataToEdit`,
onBeforeSend: (method, ajaxOptions) => {
ajaxOptions.headers = {
'Content-Type': 'application/json',
'x-auth-token': localStorage.token,
};
ajaxOptions.crossDomain = true;
},
});
I tried it I think with every possible constellation of settings and I'm searching for about 1 day in several forums before I asked this :)
maybe somebody is using the same component and can help somehow.
the error is:
Access to XMLHttpRequest at 'http://localhost:5000/api/masterData/dataToEdit' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Another solution could be that I use Axios there but was not able to integrate it.
Many thanks in advance!
You should allow Access-Control-Allow-Origin as following:
app.all('/*', function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
next();
});
Finally i found it thanks for the eye opener comments :)
the problem was that i missed at the top of the backend server.js a line i added weeks ago...
app.get('/', (req, res) => res.send(text.SERVER_API_RUNNING));
and seems if i add the cors setting then it works only for a part of my API's.

API GATEWAY - Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' when calling api from local host

I am trying to access a DynamoDB from a react app using Api Gateways and Lambda functions.
I made de API and tested the post method in https://apitester.com/, it works fine. I send a payload like {"command": "getall"} and get this response: {"statusCode": 200, "body": "\"Hello from Lambda!\""}
But when I call the API from the react app I get this error:
Access to XMLHttpRequest at
'https://9xovixi3ua.execute-api.us-east-2.amazonaws.com/default/bmsa-calc-admin'
from origin 'http://localhost:3000' 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 code looks like this:
async function getUser() {
axios.post('https://9xovixi3ua.execute-api.us-east-2.amazonaws.com/default/bmsa-calc-admin',
{
command: 'getall'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
}
From the API Gateway console I added an OPTIONS method, and then the method response header Access-Control-Allow-Origin
Thanks in advance!
So, I did a couple of things to get this to work. I added the response headers with the corresponding mapping values like this guy does. You can see that in the picture from the question.
Then, as in my case the API triggers a Lambda function, I added this to the return value of the function (python):
'headers': {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST, PUT, GET, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With'
}
So, the complete return looks like this:
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!'),
'headers': {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST, PUT, GET, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With'
}
}
This is working fine, though I'm not sure I understand what is really happening, so if anyone wishes to explain more in the comments, it would be great.

I can't perform a request from ReactJS. The header can not be written correctly

axios.get('http://localhost:8080/omp/patients', { headers: {authorization: 'Bearer ' + token}})
.then( response => {
this.state = response.data;
}
).catch(ex=> {
alert("You are not registered");
//console.log(e)
});
In network I have the field: "Access-Control-Request-Headers: authorization" but no field "authorization: token"
You will need to set the Authorization header correctly, as in the comment above.
For your reply about CORS Policy:
You will need to learn about CORS, but essentially Chrome and other browsers halt network requests if they do not have proper CORS headers set upon response. A preflight is an initial request that is sent to the same URL to learn whether the URL will support CORS, before sending the actual request. It looks like the server doesn't understand CORS preflights or isn't configured properly.
You have a couple options:
If you have access to the server configuration or code (such as a Laravel or NodeJS server), install a CORS plugin.
If you are the only user using this, you can install CORS browser extensions for Chrome or Firefox or whatever.
Change your code to this:
axios.get('http://localhost:8080/omp/patients', { headers: { "Authorization": 'Bearer ' + token}})
.then( response => {
this.state = response.data;
}
).catch(ex=> {
alert("You are not registered");
//console.log(e)
});
Also in you app.js/index.js where ever you are running your server import/require cors module and do like this:
let cors = require('cors');
app.use(cors());
Hope this helps!

CORS error when calling post api directly from client

I have a post function that I have tested and is working perfectly. When I call it from my front end, I get the following error:
Access to XMLHttpRequest at 'https://sdigg5u4xb.execute-api.eu-west-1.amazonaws.com/prod/sites' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I have tried disabling CORS and using different cognito identity pools to allow different permissions, but I still get the same error. When testing it in AWS, it is successful with no errors.
Here is where I am calling the API:
import { API } from "aws-amplify";
export default (async function submitSite(values) {
console.log(values);
return API.post("sites", "/sites", {
body: values
})
});
Here is where I am defining the function in my serverless.yml file:
createSite:
handler: CreateSite.main
events:
- http:
path: sites
method: post
cors: true
authorizer: aws_iam
I'd recommend you to check these.
Make sure you enable CORS in your API gateway as described here
Make sure your server less app have CORS enabled here.
Don't forget adding Access-Control-Allow-Origin response header to your function.
module.exports.hello = function(event, context, callback) {
const response = {
statusCode: 200,
headers: {
"Access-Control-Allow-Origin" : "*", // Required for CORS support to work
"Access-Control-Allow-Credentials" : true // Required for cookies, authorization headers with HTTPS
},
body: JSON.stringify({ "message": "Hello World!" })
};
callback(null, response);

CORS the easyway

I'm trying to 'put' data to my Laravel 5 server running on localhost from a webpage thats is also served localhost, but from other server software (nodejs). But im getting this error:
XMLHttpRequest cannot load http://localhost:8888/data/. Method PUT is not allowed by Access-Control-Allow-Methods.
The code that creates the put request is angularjs and looks like this:
return $http.put("http://localhost:8888/data/", { obj1: a, obj2: b });
What is the simplest way to get around CORS? Security is no issue.
Using the postman plug-in in chrome I'm able to send the put request.
This is my laravel setup for cors.
I've created an http.php config file with this settings:
return [
'cors' => [
'origin' => '*',
'methods' => 'OPTIONS, GET, POST, PUT, PATCH, DELETE',
'headers' => 'X-Requested-With, Content-Type, Authentication-Token',
],
];
Run this code somewhere on application startup:
if ( ! App::runningInConsole()) {
header('Access-Control-Allow-Origin: ' . Config::get('http.cors.origin'));
header('Access-Control-Allow-Credentials: true'); // to be honest i've never used this option, but it looks like you'll need it
// handle preflight requests
App::before(function() {
if (Request::getMethod() === 'OPTIONS') {
return new Response('', 200, [
'Access-Control-Allow-Methods' => Config::get('http.cors.methods'),
'Access-Control-Allow-Headers' => Config::get('http.cors.headers'),
]);
}
});
}
Postman doesn't use CORS.
To enable CORS (in the client side) add : { withCredentials: true } in your put options :
return $http.put("http://localhost:8888/data/", { obj1: a, obj2: b }, { withCredentials: true });
Note: Depending on your server application, you may enable them in the server side too.
It doesn't seem to be an Angular problem. You should try enabling CORS on the PHP with:
// Enable CORS
// In production, replace * with http://yourdomain.com
header("Access-Control-Allow-Origin: *");
header('Access-Control-Allow-Credentials: true');

Resources