AWS API gateway and authorizer CORS error - javascript

It took me awhile to realized it's not a CORS issue. I have Cognito authorizer setup with my API Gateway. I test with the my IDtoken using Postman, when the authorizer on my header is incorrect or the token is expired, postman response would tell me
{
"message": "Unauthorized"
}
{
"message": "Token expired"
}
The problem is, in my dev/localhost; I would get the results correctly if the token is correct, but when the token is bad or expired, I get a CORs error. How do I set this up so I can handle the results correctly?
Access to XMLHttpRequest at 'https://xcz3vfg4n7.execute-api.us-west-2.amazonaws.com/prod' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
xhr.js:210 POST https://xcz3vfg4n7.execute-api.us-west-2.amazonaws.com/prod net::ERR_FAILED 403

We ran into this same issue and since it was a painful to resolve, thought I would type up the solution.
Specifically we were receiving the CORs error via Axios in our React app, but not getting the error through cURL or Thunderclient (Postman-like extension for VS Code).
The resolution was actually missing headers on the "response" object from API Gateway.
Since cURL and Thunderclient/Postman don't care about CORs (because they server-based, not browser-based), those tools don't look for the 'Access-Control-Allow-Origin' header in the response.
We got back our preflight Options call 200 just fine, and then realized that the POST call was returning the 401 without an 'Access-Control-Allow-Origin' header.
Since the Authorizer is on the Method Request, it never goes past the Lambda proxy in the API Gateway and thus doesn't return full response headers.
So... the solution was actually really simple.
Go into "Gateway Responses"
Choose the "Unauthorized" option
Add the response headers (see screenshot)
IMPORTANT: Don't forget to "Redeploy" your API or the changes won't take effect
Example:

Related

How to force authentication in preflight request?

I'm trying to call Github REST API from client-side javascript (in browser).
My code does the following (I'm trying to get a zip containing the branch mkdocs_page of a private repository) :
const endpoint = 'https://api.github.com';
const resource = '/repos/astariul/private-gh-pages/zipball/mkdocs_page';
const options = {
mode: 'cors',
headers: {
'Authorization': 'Basic ' + btoa(`${pat}`), // pat contains my Personal Access Token
}
}
return fetch(`${endpoint}${resource}`, options);
But it does not work :
The preflight request fails with 404.
The console error message :
Access to fetch at 'https://api.github.com/repos/astariul/private-gh-pages/zipball/mkdocs_page' from origin 'null' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
In the process of debugging this, I tried to reproduce the problem with curl. And when I specify an authenticated request, it works :
curl --user "<my_PAT_token>" -i https://api.github.com/repos/astariul/private-gh-pages/zipball/mkdocs_page -X OPTIONS
HTTP/1.1 204 No Content
But if the request is not authenticated, it does not work :
curl -i https://api.github.com/repos/astariul/private-gh-pages/zipball/mkdocs_page -X OPTIONS
HTTP/1.1 404 Not Found
Note : it works fine when I'm trying to get the master branch (authenticated or not). However it fails after, when being redirected :
Access to fetch at 'https://codeload.github.com/astariul/private-gh-pages/legacy.zip/refs/heads/main?token=XXX' (redirected from 'https://api.github.com/repos/astariul/private-gh-pages/zipball') from origin 'null' 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.
Is it a bug in the Github API ? Or I'm doing something wrong ?
There’s no way to force authentication in a preflight request. The preflight is controlled totally by the browser, and nothing about it is exposed in any way that you can manipulate from frontend JavaScript code. And the requirements for the CORS protocol explicitly prohibit browsers from including any credentials in preflight requests.
For a detailed explanation, see the answer at https://stackoverflow.com/a/45406085/.
Since the preflight involves the browser making an OPTIONS request, then in general, if a server requires authentication for OPTIONS request to a particular resource (which seems to be the case for the GitHub URL cited in the question) that’s not at all necessarily an unintended bug.
That’s because the only normal case in which a preflight is performed and an OPTIONS request is sent is for the case of frontend JavaScript code running in a browser. Requests made from server-side code or from code running in shell/command-line environment or from desktop apps or native mobile apps don’t involve sending an OPTIONS request.
So, lack of support for unauthenticated OPTIONS requests to a particular resource would only be a bug if the provider actually intended it to be used from frontend code running in a browser. In other words, it can instead indicate the provider intentionally doesn’t want it to be used from frontend JavaScript code (which seems to be the case for the URL cited in the question).

RazorPay: getting CORS error in fetchPayment REST API

I am able to integrate RazorPay in my application. After successful payment I am trying to call RazorPay REST API fetchPayment to get the complete detail of transaction but facing below error.
Access to XMLHttpRequest at 'https://api.razorpay.com/v1/payments/pay_Fxxxxxxxxx' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
I tried with passing 'Access-Control-Allow-Origin': '*' in header but still not working.

ReactJS API Data Fetching CORS error

I've been trying to create a react web app for a few days now for my internship and I've encountered a CORS error. I am using the latest version of reactJS, and placing this in the create-react-app, and below is the code for fetching:
componentDidMount() {
fetch('--------------------------------------------',{
method: "GET",
headers: {
"access-control-allow-origin" : "*",
"Content-type": "application/json; charset=UTF-8"
}})
.then(results => results.json())
.then(info => {
const results = info.data.map(x => {
return {
id: x.id,
slug: x.slug,
name: x.name,
address_1: x.address_1,
address_2: x.address_2,
city: x.city,
state: x.state,
postal_code: x.postal_code,
country_code: x.country_code,
phone_number: x.phone_number,
}
})
this.setState({warehouses: results, lastPage: info.last_page});
})
.then(console.log(this.state.warehouses))
}
I'm sorry that I can't post the url for the API due to company rules, however, it is confirmed that there are no CORS setting in the API backend.
However, I encounter the following errors when run on mozilla
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at ------------------. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
and
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at ---------------------------------------------. (Reason: CORS request did not succeed).
If run on chrome it gives the following error
Failed to load resource: the server responded with a status of 405 (Method Not Allowed)
and
Failed to load --------------------------------------------------------: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 405. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
and
Uncaught (in promise) TypeError: Failed to fetch
Another thing is that I am able to open the url in my browsers with no problems or whatsoever.
Please help and thanks!
Additional Information
The reason I added the CORS setting is because it gives a CORS error, so removing it does not really solve the issue.
Next I tried to perform proxy setting, however, it now gives
Unhandled Rejection (SyntaxError): Unexpected token < in JSON at position 0
According to the internet this is caused becasue the response is not a JSON. However when I checked the API it gives this
api img
which means that return type should be a JSON right?
Additional Info
checking the respond will yield this
{"status":200,"total":1,"per_page":3,"current_page":1,"last_page":1,"next_page_url":null,"prev_page_url":null,"from":1,"to":3,"data":[{"id":1,"slug":"america","name":"america","address_1":"USA Court","address_2":"USA","city":"USA","state":"USA","postal_code":"94545","country_code":"US","phone_number":"10000001","created_by":null,"updated_by":null,"created_at":"2017-11-10 11:30:50+00","updated_at":"2018-06-28 07:27:55+00"}]}
The CORS settings need to be setup in the API to allow access from your React app domain. No CORS settings, no AJAX from different domains. It's simple as that. You can either add CORS settings to your company API (this is unlikely to happen) or you can work around like described below:
The CORS is solely a mechanism of client browser to protect users from malicious AJAX. So one way to work around this is proxying your AJAX request from your React app to its own web server. As Vincent suggests, the create-react-app provides an easy way to do this: in your package.json file, simply chuck "proxy": "http://your-company-api-domain". For more details, please see this link
Then in your react app you can using relative URL like this: fetch('/api/endpoints'). Notice that the relative URL has to match with your company API. This will send a request to your server, then the server will forward the request to your company API and return the response back to your app. Since the request is handled in the server-to-server way not browser-to-server so the CORS check won't happen. Therefore, you can get rid of all unnecessary CORS headers in your request.
This is what I did using vite
Package.json file add:
"proxy": "http://api_website_where_the_request_is_comming/",
App component or whatever component you making the call do this
let endpoint = /api/your_endpoint/;
fetch(endpoint).then(function (response) {
return response.json()
})
.then(function (jsonData){
console.log('Banner log', jsonData);
})
In your backend, make sure that the app is use cors.
Run this to install cors
npm install cors --save
Import cors in the app using
const cors = require('cors');
app.use(cors()) // if name of your backend is app

I'm not using the wildcard in Access-Control-Allow-Origin, but Chrome says that I am

I'm running an ionic application using ionic serve on port 8080. I do understand the preflight process and I believe I'm getting the right response:
Still, I'm getting this error:
Failed to load https://bla.bla: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. Origin 'http://localhost:8080' is therefore not allowed access. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
Then, the real request (GET) is not being sent.
What is even weirder is that just before this one request, I'm able to send a POST to the same server. The response headers are the same. The only difference in the request is that the Access-Control-Request-Headers is content-type instead of authentication
Any ideas?
Finally found the answer and it was my fault, not a chrome bug.
Thing is, some time ago I tried using this extension:
https://chrome.google.com/webstore/detail/cors-toggle/jioikioepegflmdnbocfhgmpmopmjkim?hl=en
And it didn't work for my needs, but I forgot to uinstall it. Turns out it was having some kind of conflict, since it seems to add an "Access-Control-Allow-Origin: *" header for every response. Thus it would conflict in a request with credentials (I'm guessing the Authentication header does that, not sure why tbh).
Anyway, after I uninstalled it, it's now working fine.

Pinterest API : Authentication not working : 401 (Unauthorized)

I am trying to make your javascript API work. I followed the basic setup on your js api docs. But I am getting a 401 unauthorized. I am not finding any solution how to resolve this.
I added header('Access-Control-Allow-Origin: *'); to my php code but it does not work.
Any suggestions what to do ? Thanks for authenticating. Getting your information...
pinteresturl/v1/me/:1 GET pinteresturl/v1/ 401 (Unauthorized)
(index):1 XMLHttpRequest cannot load https://api.pinterest.com/v1/me/.
No 'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://www.svenfraeys.com'; is therefore not allowed
access. The response had HTTP status code 401. sdk.js:1 The request
did not complete because of a failure on the network level.

Categories