Wikidata API Access-Control-Allow-Origin - javascript

When querying wikidata, I get a Access-Control-Allow-Origin error.
My request is sent using Axios from a Reactjs web app:
let query = "https://www.wikidata.org/w/api.php?action=wbgetentities&format=json&titles=La_Cha%C3%AEne_Info&sites=enwiki|frwiki";
axios.get(query, (response) => {
...
});
Adding origin=* as for the wikipedia api does not work and replacing www by en returns an insecure response.
Is there a way around this?

Related

How to solve CORS error while fetching an external API?

I'm developing a web app in Angular 10 that works as follows:
I'm dealing with CORS issue. I do not have permission to add code to the server I'm fetching.
I want to be able to:
Fetch the website
Parse the result, and put it in my database
I'm aiming to deploy the solution on an Apache server.
Here is the CORS error I'm dealing with:
Blocking a Cross-Origin Request: The "Same Origin" policy does not
allow viewing the remote resource located at
https://wwwfrance1.CENSORED.eu.com/api/?apikey=CENSORED.
Reason: "Access-Control-Allow-Origin" CORS header is missing. Status
code: 200.
Here is what i've tried:
Using MOSIF mozilla extension (works, but not sustainable for deployment, and for some reason, when I'm ignoring the CORS security, I cannot post on my DB any more)
Adding a header in my fetching request, such as:
/******API SEACH****/
/***Global Update***/
private updateClients() {
let xmlRequestPromise = fetch('https://wwwfrance1.CENSORED.eu.com/api/?apikey=CENSORED&service=list_clients', {
method: 'GET',
headers: {
'Access-Control-Allow-Origin': '*',
}
})
.then(async response => this.clients = this.regexSearchClient(await response.text()))
return xmlRequestPromise
}
But that doesn't work either. I've verified that the header appears in the request.
How to proceed?
What is CORS ?
Cross-origin resource sharing is a mechanism that allows restricted resources on a web page to be requested from another domain outside the domain from which the first resource was served. From wiki
In simple terms only an internal webserver can send Requests which are potentially dangerous to it's web server, and requests from other server's are simply blocked.
But few HTTP requests are allowed ,Few of the allowed methods are GET, HEAD, POST.
How do I resolve the issue ?
Apparently in this circumstance you cannot send a fetch request to a web server having CORS header. Instead you can do a GET request to the web server as a web server having CORS allows HTTP GET requests.
Note - If you send a GET request to a web server using angular in your browser it wouldn't work as browser's convert GET requests into fetch requests and fetch requests aren't allowed from a web server with CORS. Instead send a GET request from a webserver/local machine rather than a browser.
Create your own server and make a route which fetches that API. From your Angular application fetch that route on your server.
You have to use a package as a middleware. If you are using nodejs-framework expressjs.At first, you have to run npm install cors -force.Then add the code that is given bellow:-
const cors=require('cors')
app.use(cors({origin:true}))

Keycloak Introspection Endpoint

I'm trying to access to introspect endpoint in my Keycloak server /openid-connect/token/introspect from my front app, but I get next error:
Access to fetch at 'http://localhost:8180/auth/realms/backoffice/protocol/openid-connect/token/introspect' from origin 'http://localhost:8080' 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.
Using Postman, curl or Node app this request works fine, but from my front-app using fetch method thows this error. I'm not sure it's possible query for introspect endpoint from front-app in the browser or if it's only possible from server app.
Other endpoints like:
openid-connect/token:
openid-connect/userinfo:
Works fine using the Postman JS code.
Keycloak config
My client in Keycloak has set up Web Origins * and Access Type confidential.
Client Code
My front app is simply the Postman code JS, and I deploy it using node http-server.
var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/x-www-form-urlencoded");
var urlencoded = new URLSearchParams();
urlencoded.append("client_id", "my-client");
urlencoded.append("client_secret", "my-secret");
urlencoded.append("token", "eyJ...oCA");
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: urlencoded,
redirect: 'follow'
};
fetch("http://localhost:8180/auth/realms/backoffice/protocol/openid-connect/token/introspect", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
Header Response
The header response in userinfo endpoint comes with Access-Control-Allow-Origin and Access-Control-Allow-Credentials but is not present in introspect endpoint.
From the looks of it, the Keycloak server prevents the CORS headers to be set for the introspection endpoint. This could be a bug or by design. I tried it and I get the same error.
If you really want to access the introspect endpoint from the web app, you could set up a NGINX reverse-proxy in front of your Keycloak server and use it to add the missing headers.
That being said, according to oauth.com you should not leave the introspection endpoint available to the public, which is what you are currently doing since anyone can retrieve the client id and secret from your web app.
If the introspection endpoint is left open and un-throttled, it presents a means for an attacker to poll the endpoint fishing for a valid token. To prevent this, the server must either require authentication of the clients using the endpoint, or only make the endpoint available to internal servers through other means such as a firewall.
This could explain the decision not to allow CORS.
Another thing, it looks like you forgot to set the token_type_hint check out this stackoverflow post for more information.

How can I secure implement third-party API calls using JavaScript in a BigcCommerce store?

I want to make some API requests to the shipping carriers at the BigCommerce product page and I have some credential for that requests which I don't want to show in my JS code. According to the specific environment of BigCommerce I can't make any changes in back end code. I read a lot of similar questions and now have only one question.
Is it only one way to do that using my own API back end web-server which will store credential information and send POST request to the third party API? Then I will receive that information using a POST request via JS to my own API.
I have tried to run Ruby API application on the nginx web-server. However, it was unsuccessful because browser blocked my fetch() request according to the CORS Policy. I tried to add Access-Control-Allow-Origin: * parameter to the server response header writing it in ruby config file but browser didn't recognize it. Also I tried to set up configuration file on the nginx side but that didn't help me with CORS policy response. That's interesting because using Restlet Application I received response from my own API application with correct information and status "ok".
(async function application() {
let dataRuby = {
url: 'http://IP_address/index',
body: {"name": "21312", "year": "2019"}
};
function getApi(data) {
let myInit = {};
myInit.method = "POST";
myInit.body = JSON.stringify(data.body);
myInit.headers = {
'Content-Type': 'application/json'
};
let myRequest = new Request(data.url, myInit);
return fetch(myRequest).then(
res => res.json()
);
}
let response = await getApi(dataRuby);
console.log(response);
})()
Access to fetch at http://IP_address/index from origin 'null' has been blocked by CORS policy: 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.

Requesting API with fetch in javascript has CORS policy error

I'm trying to call some APIs with fetch in my javascript code. I'm developing with ReactJs in my machine and have another development in the same network developing the API with .net in another machine. With postman, I can call the API, but with fetch no. I try to call another API in other server and the result was successful.
I'm using fetch and tried to use axios too. I have found in other question in stack overflow this API: https://gturnquist-quoters.cfapps.io/api/random.
The answer says to try to fetch they and I try but throw same error again.
My code to fetch the gturnquist API:
const myHeader = new Headers();
myHeader.append('Content-Type', 'application/json');
fetch('http://gturnquist-quoters.cfapps.io/api/random', {
method: 'GET', headers: myHeader,
})
.then((res) => {
console.log(res);
return {};
})
.then(res => console.log(res));
and my code to fetch the API that i need:
const myHeader = new Headers();
const token = 'mytoken';
myHeader.append('id-tenant', token);
myHeader.append('Content-Type', 'application/json');
const id = 'myid';
const url = 'myurl';
fetch(`http://10.1.1.35/${url}/${id}`, {
method: 'GET',
headers: myHeader,
}).then(res => res.json()).then(res => console.log(res));
I have this errors when I try to call an API
OPTIONS http://10.1.1.35/url/id 503 (Service Unavailable)
Access to fetch at 'http://10.1.1.35/url/id' 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. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
Uncaught (in promise) TypeError: Failed to fetch
It's a server side error or javascript error?
In my server, the API is configured like the answer of Rajkumar Peter
EDIT: My network error
Questions i have see to try handle my error:
Fetch CORS error with instagram api
Enable CORS in fetch api
managing CORS with fetch API GET request
React fetch has error fetch was blocked by CORS policy
Response to preflight request doesn't pass access control check
When performing an API call from a web browser, it will often do something called a "preflight check". This is essentially where the browser sends a request to your API (ahead of your own API call), to check what it is allowed to do and whether it's even worth sending the actual request.
To do this, it uses the OPTIONS method (instead of GET, POST .etc).
If your API endpoint hasn't been configured to accept OPTIONS requests, then the preflight request from the browser will fail - and it will abort sending your request.
To fix your issue, you need to configure your API to accept OPTIONS methods. You should also check which origins (IP addresses of clients connecting to the API) are allowed.

ES6: Retrieve response headers from a CORS fetch call

I have a react application using ES6 fetch API to call a rest endpoint using CORS. The fetch call work just fine, but I'm unable to get the response headers that are being sent from the server. I can see the response headers in Chromes devtools so I know they are being sent back to me; however access to them in code doesn't seem to work for me. Here is the code (its basic fetch promise-chaining):
fetch(url)
.then(response => {
for (let header of response.headers) { < -- - headers is empty
console.log(header);
}
return response;
});
But response.headers is empty. But I can clearly see the headers in Chrome. Is there a reason why the fetch call is blocking me from viewing them? What do I need to get access to these headers? The server stores some application specific headers that we would love to use.
UPDATE: I was able to fix this by having the server add this to the response of the OPTION request:
response.setHeader("Access-Control-Expose-Headers", "X-Custom-Header");
Now on the response of the fetch command, I can do the following:
const customHeader = response.headers.get('X-Custom-Header');
Thank you Karim for the help on this!
To get a specific header you need to call response.headers.get(key)
and the iterable object is response.headers.entries and not response.headers
for (let header of response.headers.entries()) {
console.log(header);
}
https://developer.mozilla.org/en-US/docs/Web/API/Headers/entries
In addition, in a cors scenario only some headers are exposed to the app, thus not all the headers you see on the chrome dev tools are necessarily available at application level.
For further details check this answer:
Reading response headers with Fetch API

Categories

Resources