Converting cUrl token call to axios - javascript

I am trying to authenticate and API by calling to a seperate server, receiving a token to store, which is then used to Auth and API.
At the moment I have a token hardcoded in, because every time I submit a request with axios it returns "error": "invalid_request"
This cUrl script works fine curl -v -X POST -u "username:password" -d "grant_type=client_credentials" https://thewebsite/token -H 'cache-control: no-cache' and I can connect with Postman when I imported and added Basic Auth. I have tried to copy all the settings in, so many different ways.
I need to create an axios instance that is then passed to another function for the actual POST operation:
const settings = {
baseURL,
timeout: 5000,
headers: {
Accept: 'application/json',
'Content-Type': 'application/x-www-form-urlencoded',
'cache-control': 'no-cache',
},
auth: {
username: username
password: password
},
data: {
grant_type: 'client_credentials',
},
};
this.axiosInstance = axios.create(settings);
In Postman the response looks like this:
"access_token": string,
"expires_in": 3600,
"token_type": "bearer"
I feel like it is an obvious syntax error, like the details need to be sent as a param or a header.

Related

How to post body data using Fetch API?

Below is the curl command that gives back the response successfully upon importing and running in postman.
curl --request POST \
--data "grant_type=password" \
--data "username=test" \
--data "password=xyz1234" \
--data "scope=write" \
--data "client_id=test" \
--data "client_secret=test12" \
"https://example.com/access_token"
Below is how I am sending data using fetch api in my js code.
const response = await fetch ('https://example.com/access_token',
{
'credentials' : 'include',
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ grant_type:'password',username:'test',password:'xyz1234',scope:'write',client_id:'test',client_secret:'test12'}),
})
However the equilavent curl which is generated after copying from chrome developer tools is below.
curl --request POST \
--data-raw '{"grant_type":"password","username":"test","password":"xyz1234","scope":"write","client_id":"test","client_secret":"test12"}'
"https://example.com/access_token"
I suspect that the body data is not constructed in the correct format. This may be leading to a 400 error code response. How should I send the data using fetch api equilavent to working curl command?
Looking at the curl your data does seem to be URL encoded. So as it's not expecting JSON don't serialize it to a JSON string.
const headers = new Headers({
"Content-Type": "application/x-www-form-urlencoded"
});
const urlencoded = new URLSearchParams({
"grant_type": "password",
"username": "test",
"password": "xyz1234",
"scope": "write",
"client_id": "test",
"client_secret": "test12",
});
const opts = {
method: 'POST',
headers: headers,
body: urlencoded,
};
fetch("https://example.com/access_token", opts);
EDIT
As #Kaiido mentioned in the comments. It is not necessary to set the Content-Type header explicitly as the browser will do that automatically, but I have done it here to show you that it should not be set to application/json but to application/x-www-form-urlencoded.

cURL with -F Option into NodeJS with Axios

I'm attempting to convert this CURL command
curl -X POST "https://serverless-upload.twilio.com/v1/Services/ZS5798711f7bee1284df67427071418d0b/Assets/ZH4912f44da25f4b1a1c042a16a17f2eac/Versions" \
-F Content=#./mapping/mapping.json; type=application/json \
-F Path=mapping.json \
-F Visibility=private \
-u username:password
into a post request using the package axios,
I've tried
url = `https://serverless-upload.twilio.com/v1/Services/${service_uid}/Assets/${asset_uid}/Versions`
data = {
'Path': 'mapping.json',
'Visibility': 'private',
'Content': JSON.stringify(mapping),
'filename': 'mapping.json',
'contentType': 'application/json'
}
await axios.post(url, data, {
auth : {
user: `${accountSid}:${authToken}`
},
headers: {
'Content-Type': 'multipart/form-data',
}
}).then((r) => console.log(r));
but I'm unsure if this is malformed or not
Twilio developer evangelist here.
The Twilio Node library actually uses axios under the hood, you can see it in action in the RequestClient. We also have a stand-alone Serverless API client which is part of the Twilio Serverless Toolkit you can use, but it is written with got instead.
You can use the Serverless API module to save yourself the work of recreating this request.
If you decide to continue with axios, here are the changes you should make.
Auth
Authorization is done via the Authorization header, passing a base 64 encoded string made up of the account Sid and auth token.
headers: {
Authorization: 'Basic ' + Buffer.from(`${accountSid}:${authToken}`).toString('base64')
}
Data
When uploading an asset, it is done as multipart form data. To build up multipart data in Node.js you can use the form-data module. Something like this should work:
const FormData = require("form-data");
const form = new FormData();
form.append("Path", "mapping.json");
form.append("Visibility", "private");
form.append("Content", JSON.stringify(mapping));
form.append("filename", "mapping.json");
form.append("contentType", "application/json");
await axios.post(url, form, {
headers: {
Authorization: 'Basic ' + Buffer.from(`${accountSid}:${authToken}`).toString('base64'),
...form.getHeaders(),
},
}).then((r) => console.log(r));
Let me know how you get on with that.

Unable to get access token for linkedin using axios

I am trying to get access token following the steps described in Linkedin Oauth. I am trying to perform step 2 in the process to get an access token. I am using Axios for the POST request. Here is the code I am using (The client secret and id is not real for security reasons):
const axios = require('axios');
const qs = require('qs');
axios({
method: 'post',
url: 'https://www.linkedin.com/oauth/v2/accessToken',
data: qs.stringify({
grant_type: 'authorization_code',
code: 'AQSow7V6s2F2koWzIsnVKcQGt_cHtsM1F3FHZOrEV0UY1KIFkWiFJpi8dt1NtjuZMOO6-NStoCjTf58awk6GBcH2XQRctt7IBtel4Oeop5yVIBqiedk8qxlIlbkMxlfGg1gCVoupXL6xUc3-jegKYDPSe0rl4mygdpIzGdej2_hhJ827vJcojtvaMXCCGw',
redirect_uri: 'https%3A%2F%2Fwww.linkedin.com%2Fcompany%2Ftttrrr878',
client_id: '99blt2z20qlm3d',
client_secret: 'fGGgdqqcx5t3cRfw'
}),
headers: {
content-type: 'application/x-www-form-urlencoded;charset=utf-8'
}
}).then(result => {
console.log(result.data);
}).catch(error => {
console.log(error);
});
I get the following error when I run the code even after making sure that the code is not expired (before the 30 min expiration time):
data: {
error: 'invalid_redirect_uri',
error_description: 'Unable to retrieve access token: appid/redirect uri/code verifier does not match authorization code. Or authorization code expired. Or external member binding exists'
}
However when I do the same thing using curl in the command line as follows, I am able to get the access code:
curl -ik -X POST https://www.linkedin.com/oauth/v2/accessToken \
-d grant_type=authorization_code \
-d code=AQSow7V6s2F2koWzIsnVKcQGt_cHtsM1F3FHZOrEV0UY1KIFkWiFJpi8dt1NtjuZMOO6-NStoCjTf58awk6GBcH2XQRctt7IBtel4Oeop5yVIBqiedk8qxlIlbkMxlfGg1gCVoupXL6xUc3-jegKYDPSe0rl4mygdpIzGdej2_hhJ827vJcojtvaMXCCGw \
-d redirect_uri=https%3A%2F%2Fwww.linkedin.com%2Fcompany%2Ftttrrr878 \
-d client_id=99blt2z20qlm3d \
-d client_secret=fGGgdqqcx5t3cRfw
Any idea why this is happening? Is it somehow related to this
issue ?
Your code looks correct. The issue is because you are url encoding the redirect_uri parameter, remove that and it should work.
You only need to url encode the redirect_uri parameter when doing the initial request for the access code from the browser.

How do I transform this curl request with javascript axios

I want to perform a request to the Google speech API, to return the translation of audio I sent to the API
If I use the curl command below, I successfully retrieve the data, but I don't know how to pass it to an Axios request.
curl command:
curl -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) -H "Content-Type: application/json; charset=utf-8" "https://speech.googleapis.com/v1/operations/{speech_name}"
// creating axios
const api = axios.create({
baseURL: https://speech.googleapis.com/v1/operations,
crossDomain: true,
responseType: 'json',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization':'your_key
},
});
// calling api
api.get('/speech_name')
.then(res=>{
console.log(res);
}).
catch('error');
Note : you can use other request method also api.post(url)

Using React and axios for curl

Is it possible to make a curl request by using axios?
the curl string is:
curl -v 'https://developer.api.autodesk.com/authentication/v1/authenticate' --data 'client_id=1234&client_secret=1234&grant_type=client_credentials&scope=bucket:create bucket:read data:write data:read viewables:read' --header 'Content-Type: application/x-www-form-urlencoded' -k | jq '.'
I tried to do this:
getToken() {
axios.get({
url: 'https://developer.api.autodesk.com/authentication/v1/authenticate',
data: {
client_id: '1234',
client_secret: '1234',
grant_type : 'client_credentials',
scope: 'data:read data:viewables'
},
beforeSend: function(xhr) {
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
}, success: function(data){
console.log(data)
}
})
}
But with no luck - e.g. nothing happens.
I previously used the cygwin-terminal to make the curl-request and I succesfully got the response
{
"token_type": "Bearer",
"expires_in": 1799,
"access_token": "eyJhbGciOiJIUzI1NiIsImtpZCI6Imp3dF9zeW1tZXRyaWNfa2V5X2RldiJ9.eyJjbGllbnRfaWQiOiJjWTFqcm1rQXhPSVptbnNsOVhYN0puVURtVEVETGNGeCIsImV4cCI6MTQ4NzU2NzgwMSwic2NvcGUiOlsiZGF0YTpyZWFkIl0sImF1ZCI6Imh0dHBzOi8vYXV0b2Rlc2suY29tL2F1ZC9qd3RleHAzMCIsImp0aSI6InJZcEZZTURyemtMOWZ1ZFdKSVVlVkxucGNWT29BTDg0dFpKbXlmZ29ORW1MakF0YVVtWktRWU1lYUR2UGlnNGsifQ.uzNexXCeu4efGPKGGhHdKxoJDXHAzLb28B2nSjrq_ys"
}
So, is this possible with React/axios?
In addition to the question, can I pass the received token to another curl request?
Well it's not really "a curl request". It's an HTTP request. Curl is just the tool you use to do HTTP (and other) actions via the command line.
In your HTTP request, I can see you're using axios.get(), however you're trying to do a post request (you've got a data object you're trying to send). So you should be using axios.post(). It'd be best to check out the axios page to see the syntax for HTTP posts, including how to include the data and header objects in the post.
In answer to your second question, yes you can. In the .then() section of your first axios post, you can do another axios post using the response, e.g.
axios.post(
...
).then(response => {
// do another post with response.token or whatever as the data
})
...

Categories

Resources