I've created a client-side application that makes an API call. The issue with this, however, is that in order to make the API call, I have to use an API Key. If I make the call client-side, the user will be able to see the API key. How do I avoid this? Well, if the answer is to call the API server-side, how do I do that? There seems to be little information wherever I look regarding server-side programming, and if anyone could lead me in the right way, it would be great.
You have to set it in the header with bearer
let config = {
headers: {
'Authorization': 'Bearer ' + KEY
}
};
Axios.get('http://url', {}, config )
.then( (response) => {
console.log(response)
})
.catch();
Related
I'm trying to build a reddit-like app on react native, so i'm using axios to fetch requests to Reddit Api and I can't seem to be able to fetch any POST requests, I've tried everything I can, I'm trying to subscribe to a subreddit, here is my request :
subscribe: async function subscribe(action, sub, modhash) {
try {
const token = await this.getAccessToken();
console.log('token: ' + token)
let Headers = {'Authorization': 'Bearer ' + token,
'Content-Type': 'application/json',
'X-Modhash': modhash}
let Params = {'action': action, 'sr_name': sub}
let Body = {'api_type': "json", "extension": "json"}
await axios.post('https://oauth.reddit.com/api/subscribe', Headers, Params, Body)
.then((response) => {
console.log('sub: ' + JSON.stringify(response.data));
console.log("Subbed to " + sub)
})
} catch (error) {
throw 'Could not sub: ' + error
}
},
Here is the Catch result:
"Could not sub: Error: Request failed with status code 403"
here is the official api about subscribe : https://www.reddit.com/dev/api/#POST_api_subscribe
action = "sub" and sr = "t5_2qh03" and I tried sr_name and sr but none seems to work, I'm sure the token is valid since it works with other GET requets I can't find what I did wrong here. Do you guys have any idea on what I'm missing ?
Edit: I've tried the same request with postman and the request actually worked, i did sub to a subreddit, but the same exact request is not working with axios, does my request is okay ?
To me, your code is alright.
However, the Reddit API is such a clusterfuck, that peoples are not much using it.
They are using pupeeter and similar.
For your problem, it all depends of the subreddit, some (many) are not allowing to POST by API at all, of course without warning, or with totally unclear HTTP error codes It just doesn't work.
There is also situations where it works, but only sometimes, or only the first time, or only from an IP of a given allowed country.
They are also widely using black/grey/white listing, shadow banning, and rate limiting. But no notices are ever given. The definition of a clusterfuck.
I made an api using Net.Core 'https://localhost:44351/api/usuarios' with Authorize attribute for use a validation token for access to this api. This token is generated by another api and works well.
When i use Postman for acess to api 'https://localhost:44351/api/usuarios' i need put in the Authorization tab the token previously generated (see https://i.ibb.co/Lg7rD4N/2.png) and this way i get access for the api (see https://i.ibb.co/0BqnPhR/3.png)
But the huge problem is when i try from a JAVASCRIPT CLIENT use method GET using FETCH. I know need to do a object like this for make correct request
let params= { method: 'GET',
headers: {"X-Auth-Token": "5f5fe128570248a9bd198add1a5b25e4"}
};
So my question is how i can implement the attributte 'Temporary-Headers' in the object 'params' like Postman does ( https://i.ibb.co/0BqnPhR/3.png)?
"Temporary Headers" are just like any other Header, those are just values auto-generated by the web client. I believe your problem relies on how you send your Header if you are using the fetch API modify your parameters like the following.
{
method: 'GET',
headers: {
"Authorization": "Bearer <replace with your token>"
}
}
This is how postman is sending the request as seen in the screenshots you provide.
I'm trying to get an OAuth token for the Reddit API following the Application Only OAuth instructions. My reddit app is an installed app, so for my grant_type I'm using https://oauth.reddit.com/grants/installed_client.
Currently I'm running a very short JS script to query the API and get a token:
const APP_ID = 'MY_APP_ID'
const DEVICE_ID = 'TRACKING_ID_20_TO_30_CHARS'
let form = new FormData()
form.append('grant_type', 'https://oauth.reddit.com/grants/installed_client')
form.append('device_id', DEVICE_ID)
fetch('https://www.reddit.com/api/v1/access_token', {
method: 'POST',
headers: new Headers({
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': `Basic ${btoa(`${APP_ID}:`)}`,
}),
body: form })
.then(handleResponse)
.then(function(data) {
console.log(data)
})
.catch(error => console.error(error))
function handleResponse(response) {
return response.json()
}
(Note: running the snippet as-is will give you a NetworkError because the APP_ID isn't a real one and I don't want to give mine out.)
The response I get is:
{
"error": "unsupported_grant_type"
}
When I try the same API request using a REST client I get back the expected response, so this makes me think that the problem is JavaScript-related. Since the grant_type matches what the instructions say I'm not really sure what to do with the error. I'm hoping someone else more experienced with OAuth will know what is going on here.
The problem was the use of the FormData object. In earlier stages of troubleshooting I found this answer on Reddit and decided to use it, but that didn't work for me.
It was submitting the data as multipart/form-data rather than application/x-www-form-urlencoded, which Reddit's OAuth server did not like. I wrote a helper function based on this answer which did the trick:
function urlEncode(data) {
let out = [];
for (let key in data) {
out.push(`${key}=${encodeURIComponent(data[key])}`);
}
return out.join('&')
}
I've come across this problem a few times now and I feel like there's someone out there who knows a better way to troubleshoot api calls than i - specifically request headers.
Often when i need to pass my api token via a request header, I am constantly groping at the exact format to pass my key's (it seems there's not a universal format for doing this).
For example, I am currently trying to access the vultr v1 api. The docs give a curl example where API-Key: SOMEKEY needs to be passed, yet, my first attempt rarely works then i'm just groping... Do they want my key in a key/value pair or a single string in an array? Do i use es6 objects (without quotes) or not.
here's what i mean:
// one method
const opts = {
headers: {
API-Key: 'SOMEKEY'
}
}
// another
const opts = {
'headers': {
'API-Key': 'SOMEKEY'
}
}
// another
const opts = {
headers: [
'API-Key: SOMEKEY'
]
}
axios.get(url, opts).then(res => console.log(res.data))
which is the proper way? In the curl example given by vultr it shows:
curl -H 'API-Key: EXAMPLE' https://api.vultr.com/v1/iso/list
I also see in my network inspector that the request headers show i am passing my API key yet i am still getting a 403 (bad key error)
I have double checked the validity of my key and that's not the problem.
My question is this:
How do i find the correct format for the headers? Is there a better troubleshooting method for this kind of problem? Any help would be greatly appreciated. Thanks ya'll
UPDATE:
Turns out they've got access control based on IP's. I hadn't noticed it till just now. They were blocking my request because of this. My question still stands however. Good methods for figuring out correct formats? Is there a correct format?
One way is setting Headers while creating axios object, as follows :
axios = axios.create({headers: {'API-Key': 'EXAMPLE'}});
axios.get(url, opts).then(res => console.log(res.data))
Or
axios.get(url, {headers: {'API-Key': 'EXAMPLE'}}).then(res => console.log(res.data))
I can fetch a list of blog posts from Google Cloud Endpoints using the Javascript Client:
gapi.client.blog.posts.list().execute(function (resp) {
console.log(resp);
});
But I need to set a custom header value in the Google Cloud Endpoints request that contains a user token (this could be an access token from Facebook). How can I do that using the Javascript Client from Google? I could solve this by not using the Javascript Client from Google, but I would rather use it.
https://developers.google.com/appengine/docs/java/endpoints/consume_js
https://developers.google.com/api-client-library/javascript/reference/referencedocs
edit
It seems I can pass the custom header value like this:
gapi.auth.setToken({
access_token: 'this is my custom value'
});
Doesn't seem good practice though. Is there a better way to do this?
You can now do this using gapi.client.request, for example:
gapi.client.init({
'clientId': 'YOUR_WEB_CLIENT_ID.apps.googleusercontent.com',
'scope': 'your_scope'
}).then(function() {
return gapi.client.request({
'path': 'http://path/to/your/endpoints/api',
'headers': { 'mycustomheader': 'myvalue' }
})
}).then(function(response) {
console.log(response.result);
}, function(reason) {
console.log('Error: ' + reason.result.error.message);
});
See also the Getting Started page of the Google API Javascript Client documentation.
Try using the header normally, but fetching the token and adding a variable containing it where you need the token to show.