coinmarketcap api integration - 401 error - JavaScript - javascript

I am trying to integrate coinmarketcap api but cannot really get the data. I registered, got the API key, and wrote the following method to fetch the data:
let getPostsList = async () => {
const options = {
method: 'GET',
headers: {
'X-CMC_PRO_API_KEY': 'api-key-goes-here'
},
mode: 'no-cors'
};
try {
const response = await fetch(`https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest`, options);
const json = await response.body;
// console.log(json)
return json
} catch (err) {
console.log('Error: ', err)
}
};
All I get is 401 error, like this:
GET https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest
401
Any suggestions what I should fix? Docs says that 401 is likely connected to API key, but they say to provide it in the headers like the above...

From what I've tested after getting my own API key, the no-cors mode is problematic. You will need to use CORS, where https://cors-anywhere.herokuapp.com/ comes into handy.
Just send the request like this :
const options = {
method: 'GET',
headers: {
'X-CMC_PRO_API_KEY': 'api-key-goes-here'
},
};
try {
const response = await fetch(`https://cors-anywhere.herokuapp.com/https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest`, options);

Related

How to use POST api token to use third party APIs in nextjs

I need to POST to a third party api route to receive an access token to be authorized to fetch data from their endpoints, but I'm not sure how to use the token. They are using Swagger:
export default async function() {
const res = await fetch('url', {
method:'POST',
headers: {
accept: 'application/json'
}
});
const data = await res.json()
console.log(data)
}
I get in response:
{
access_token: 'my token...',
...
}
But I'm not sure how I'd use this response to authorize fetching data. Do I need to pass the token to the headers in the fetch?
export async function getStaticProps() {
const res = await fetch( `url`, {
headers: {
accept: 'application/json',
}
});
const data = await JSON.stringify(res);
return {
props: {
items: data
},
};
}
I can't seem to find much info on this, or I'm just searching for the wrong things. I'm not sure if I'm understanding this correctly
Likely you'll need to send that token in an Authorization header with the request, something like this:
const res = await fetch(`url`, {
headers: {
accept: 'application/json',
Authorization: `Bearer ${token}`,
}
});
const json = await res.json()
const data = JSON.stringify(json);
The API docs should be able to tell you specifics though, if you're still having issues please post the API docs if they're public!

cross origin for amazon lambda function from localhost in gatsby site

I have the following code which works when I run it as a local serverless function with netlify dev, but I need it to run cross origin from a dev server to the hosted server function. I put the function in a aws lambda function but I am getting a cross origin blocked error on my https:dev.website.com, I thought I have the correct headers in the return object so not sure why I am getting a cross origin error.
Any help would be great
const sanityClient = require("#sanity/client");
const client = sanityClient({
projectId: "random-id",
dataset: "production",
useCdn: true,
});
exports.lambdaHandler = async (event, context) => {
var body = JSON.parse(event.body);
//console.log(body.price_id)
try {
const checkPriceId = async (test) => {
const query = `*[_type == "products" && price_id == "${body.price_id}"]`;
const documents = await client.fetch(query, {}); // this could throw
return documents.map((document) => document.sold);
};
var ok = checkPriceId().then((test) => {
return new Promise(function (resolve, reject) {
//console.log(test) // this will log the return value from line 7
console.log(test);
resolve(test);
});
});
var bools = await ok;
// prettier-ignore
return {
statusCode: 200,
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Allow-Methods':'GET, POST, OPTION',
},
body: JSON.stringify({
sold: bools,
}),
};
} catch (err) {
return { statusCode: 500, body: err.toString() };
}
};
This is my request to the function if that helps
var fetchUrl = https://random.executue-api.aws.com/prod/sold //not exact
var fetchData = async function () {
const response = await fetch(fetchUrl, {
method: "post",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
price_id: final,
}),
})
.then(res => {
return res.json()
})
.catch(error => console.log(error))
return response
}
Update:
I tried adding cors the way suggested in the answer below, but it failed seen below so I tried manually adding the method response seen after.
I still get a cross domain error. And I have changed the domain so it is now https as well. Really stuck here.
I was looking into this more, and it seems like before it does the actual post it does a cors check at the options method, so I added in the same access control headers, and deployed but did not work. Don't quite get this.
Your headers look ok to me. (note: If you mix HTTP and HTTPS you are most likely to get a mixed content error in the client). If it is ONLY a CORS issue that you are seeing in the console in the web browser, then you might not have configured the API Gateway correctly in AWS.
In AWS, go to API Gateway and you should see something like the below:
Make sure that you enable CORS and then redeploy.
UPDATE:
Just looking at a previous implementation of a lambda function I setup with AWS. The headers I declared were as follows:
headers: {
"Content-Type" : "application/json",
"Access-Control-Allow-Origin" : "*",
"Allow" : "GET, OPTIONS, POST",
"Access-Control-Allow-Methods" : "GET, OPTIONS, POST",
"Access-Control-Allow-Headers" : "*",
"Access-Control-Allow-Credentials" : true
}
Your headers look OK to me though. However, when you created the method in the API Gateway, did you select Use Proxy Lambda Integration? (see screenshot).
Your client side fetch request looks ok. For reference mine was:
const url = 'your url';
const options = {
method: 'POST',
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data),
};
fetch(url, options).then(res => res.json());
Unrelated to this issue, but its not advisable to mix Async/Await with .then promise chaining. But this isn't the issue you are having. Just something to note.
Check the values from your Integration Response / try setting them manually for both OPTIONS and POST (and if that works, make sure you are passing through the response correctly from the lambda).
Your POST action should only require the Access-Control-Allow-Origin header. The other two (Access-Control-Allow-Methods, Access-Control-Allow-Headers) belong in the OPTION action. See this writeup, and note the full example exchange for a preflighted request (in grey): https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#preflighted_requests

Typescript removes Authorization header from POST and PATCH fetch requests

I've built an API using C# that uses JWT tokens for authorization. On the frontend I store these tokens in local storage and get them, when creating a request. When creating GET or DELETE requests, everything works fine, and using console.log() I can see that fetch options have the Authorization header added. However when using POST or PATCH methods, the Authorization header is missing immediatly after adding it to the object. Here is my request method:
const send = async (apiOptions: ApiParams): Promise<FetchReturn> => {
const accessToken = GetAccessToken()
const options: ApiOptions = {
method: apiOptions.method,
headers: {
Authorization: `Bearer ${accessToken}`
}
}
console.log(options)
if (apiOptions.data) {
options.headers = {
'Content-Type': 'application/json'
}
options.body = JSON.stringify(apiOptions.data)
}
const result = await fetch(`${getUrl()}/${apiOptions.path}`, options).then(res => res).catch(err => err)
if (!result.ok) {
if (IsExpired()) {
const refreshResult = await fetch(`${getUrl()}/api/user/refresh`, {method: 'POST', headers:{
'Content-Type': 'application/json'
}, body: JSON.stringify(GetRefreshRequest())}).then(res => res).catch(err => err)
if (refreshResult.ok) {
Login(JSON.parse(await refreshResult.text()))
return await send(apiOptions)
} else if (refreshResult.status === 401) {
Logout()
window.location.reload()
return { code: 0, text: ""}
}
}
}
const text = await result.text()
return { code: result.status, text: text }
}
I suppose that in apiParams for POST you have property 'data' assigned, and later you have if-condition that completely replaces request headers object.
Change it to:
options.headers['Content-Type'] = 'application/json';
To keep authorization in headers
The first time check your apiOptions.data
i think , its null when you call POST/Patch request
Just put console.log("...") In the if statement , Then try for resolve your Error
If your problem not resolved, put a replay under my post

Phonegap: Is there a way to get JSON data from an external url?

Actually am kinda disappointed as I tried many things and checked out many articles but non worked out for me.
function demo() {
console.log("Booooooooooooommmmmmmmmmm");
tokenV = document.getElementById("tokenString").value;
var urlF = "https://***********.com/connect/api.php?action=2&token="+tokenV;
const myHeaders = new Headers();
const myRequest = new Request(urlF, {
method: 'GET',
headers: myHeaders,
mode: 'cors',
cache: 'default',
});
fetch(myRequest)
.then(response => response.json())
.then(data => console.log(data));
}
I have already whitlist the domain inside my config file, am using phonegap CL latest version. I'm trying to connect to an api which will out put json.encode data if token were right.
Error output:
(index):50 Fetch failed loading: GET https://*******.com/connect/api.php.............
Another way I tried using cordova fetch plugin still failed:
function demo() {
console.log("Booooooooooooommmmmmmmmmm");
tokenV = document.getElementById("tokenString").value;
var urlF = "https://*********.com/api.php?action=2&token="+tokenV;
console.log("nowww1");
cordovaFetch(urlF, {
method : 'GET',
headers: {
'User-Agent': 'CordovaFetch 1.0.0'
},
})
.then(function(response) {
return response.json();
}).then(function(json) {
console.log('parsed json', json);
}).catch(function(ex) {
console.log('parsing failed', ex);
});
}
Error out put:
Error: exec proxy not found for :: FetchPlugin :: fetch (index):118 parsing failed TypeError: Network request failed
I can change the out put as I want but show me away to get the data from an external server???
Thank you

How to make a fetch request with custom herokuapp proxy?

I'm trying to make a fetch request with custom herokuapp proxy to an API, but when I do that it gives an error. Error says "There is no Target-Endpoint header in the request". Here is my code.
var userTargetUrl = `http://api.steampowered.com/ISteamUser/ResolveVanityURL/v0001/?key=${steamApiKey}&vanityurl=${url}`
const response = await fetch(proxyUrl + userTargetUrl, {
headers: {
'Target-Endpoint': 'http://api.steampowered.com/ISteamUser/ResolveVanityURL/v0001/?'
}
})
const data = await response.json()
url = data['response']['steamid']
I'm following their instructions, but I couldn't figure it how to do it.
I won't pretend to be entirely sure, but maybe you can try
const response = await fetch(proxyUrl, {
headers: {
"Target-Endpoint": userTargetUrl
}
});

Categories

Resources