I have a small Spotify app that I am trying to convert to use the axios http library. I am having an issue with the callback when logging in. Up to this point I have been using request like is in all of the Spotify documentation. Everything works fine with request, but even though everything looks the same with axios, I get a 500 Internal Server Error. Here is my code to make the http request:
var authOptions = {
method: 'POST',
url: 'https://accounts.spotify.com/api/token',
form: {
code: code,
redirect_uri: REDIRECT_URI,
grant_type: 'authorization_code'
},
headers: {
'Authorization': 'Basic ' + (new Buffer(CLIENT_ID + ':' + CLIENT_SECRET).toString('base64'))
},
json: true
};
axios(authOptions).then(res => {
console.log(res)
})
I can pass the same authOptions object to the request library everything works fine. Here is my request from axios logged out to the console.
{
method: 'POST',
url: 'https://accounts.spotify.com/api/token',
form:
{ code: 'changedthecode',
redirect_uri: 'http://localhost:8888/callback',
grant_type: 'authorization_code' },
headers: { Authorization: 'Basic changedthecode=' },
json: true,
timeout: 0,
transformRequest: [ [Function] ],
transformResponse: [ [Function] ],
withCredentials: undefined
}
And here is my response with the axios library:
{ data: { error: 'server_error' },
status: 500,
statusText: 'Internal Server Error',
headers:
{ server: 'nginx',
date: 'Fri, 04 Dec 2015 14:48:06 GMT',
'content-type': 'application/json',
'content-length': '24',
connection: 'close' },
config:
{ method: 'POST',
headers: { Authorization: 'Basic changedthecode' },
timeout: 0,
transformRequest: [ [Function] ],
transformResponse: [ [Function] ],
url: 'https://accounts.spotify.com/api/token',
form:
{ code: 'changedthecode',
redirect_uri: 'http://localhost:8888/callback',
grant_type: 'authorization_code' },
json: true,
withCredentials: undefined }
}
The only option that I didn't know about from axios was withCredentials, and it didn't work when it was set to false or true. What else am I missing?
The problem is that I was posting a form and was not encoding it when going across the wire and I was not setting the Content-Type. I changed my authOptions to:
var authOptions = {
method: 'POST',
url: 'https://accounts.spotify.com/api/token',
data: querystring.stringify({
grant_type: 'refresh_token',
refresh_token: refreshToken
}),
headers: {
'Authorization': 'Basic ' + (new Buffer(CLIENT_ID + ':' + CLIENT_SECRET).toString('base64')),
'Content-Type': 'application/x-www-form-urlencoded'
},
json: true
};
and everything worked fine.
Related
I am using the following code to make a POST request to https://accounts.spotify.com/api/token in order to receive a refreshed access token although every time I've tried I get an Error 400 (Bad Request)
$.ajax({
url: 'https://accounts.spotify.com/api/token',
type: 'post',
Headers: {
'Authorization': 'Basic ' + btoa(ClientID ':' ClientSecret),
'Content-Type': 'application/x-www-form-urlencoded'},
body: {
grant_type: 'refreshtoken',
refresh_token: RefreshToken
},
json: true
});
I want to call the API POST method with axios, I did it with postman with header configuration like, and it return the results
and the body request looks :
it return error when I call by axios this my script, anyone can help me what I suppose todo from the axios side ?
const header = {
headers: {
'Content-Transfer-Encoding': 'application/json',
'content-type': 'application/json',
'HTTP_API_KEY': 'xxxxx',
}
}
axios({
method: 'POST',
url: URL,
headers: header,
data : {
}
})
.then((response) => {
if (response.status !== 200) {
return res.send(respone("500", response.data.result.data))
} else {
return res.send(respone("200", response.data.result.data))
}
})
.catch((error) => {
console.log(error);
return res.send(error)
})
the error show
{
"message": "Request failed with status code 404",
"name": "AxiosError",
"config": {
"transitional": {
"silentJSONParsing": true,
"forcedJSONParsing": true,
"clarifyTimeoutError": false
},
"transformRequest": [
null
],
"transformResponse": [
null
],
"timeout": 0,
"xsrfCookieName": "XSRF-TOKEN",
"xsrfHeaderName": "X-XSRF-TOKEN",
"maxContentLength": -1,
"maxBodyLength": -1,
"env": {},
"headers": {
"Accept": "application/json, text/plain, */*",
"Content-Type": "application/json",
"Content-Transfer-Encoding": "application/json",
"HTTP_API_KEY": "xxxx",
"User-Agent": "axios/0.27.2",
"Content-Length": 2
},
"method": "post",
"url": "xxxxx",
"data": "{}"
},
"code": "ERR_BAD_REQUEST",
"status": 404
}
It seems you nested your headers inside another "headers" property.
Basically you're doing this
headers: {
headers: {
'Content-Transfer-Encoding': ...
}
}
As Zai showed in her answer you problem is your header variable:
const header = {
headers: {
'Content-Transfer-Encoding': 'application/json',
'content-type': 'application/json',
'HTTP_API_KEY': 'xxxxx',
}
}
is nested, when you do this:
axios({
method: 'POST',
url: URL,
headers: header,
data : {
}
what you are really doing is:
axios({
method: 'POST',
url: URL,
headers: headers: {
'Content-Transfer-Encoding': 'application/json',
'content-type': 'application/json',
'HTTP_API_KEY': 'xxxxx',
},
data : {
}
So your header: instead of being Content-transfer etc... is just 'headers'
try this:
const header = {
'Content-Transfer-Encoding': 'application/json',
'content-type': 'application/json',
'HTTP_API_KEY': 'xxxxx',
}
also, i recommend you to do a console.log with your api call in order to find this problems faster and compare with postman, really helpful in develop phase (just use it in local, never push that log to production)
Using Spotify Documentation for Client Credential Flow
(https://developer.spotify.com/documentation/general/guides/authorization/client-credentials/)
I was able to create an API request in javascript:
function getoAuth () {
const client_id = id;
const client_secret = secret;
fetch("https://accounts.spotify.com/api/token", {
method: 'POST',
headers: {
'Content-type': 'application/x-www-form-urlencoded',
'Authorization': 'Basic' + (client_id + ":" + client_secret).toString('base64')
},
form: {
grant_type: 'client_credentials',
},
json: true
})
}
But I'm receiving the following error: {"error":"unsupported_grant_type","error_description":"grant_type parameter is missing"}
Why is this failing?
Check the fetch library docs, you have to pass the formdata through body field.
https://developer.mozilla.org/en-US/docs/web/api/fetch
fetch("https://accounts.spotify.com/api/token", {
method: 'POST',
headers: {
'Content-type': 'application/x-www-form-urlencoded',
'Authorization': 'Basic<>'
},
body: new URLSearchParams({
'grant_type': 'client_credentials'
}),
json: true
})
I am trying to use the tiny.cc REST API from Node, but seem to be hitting an issue since the Server always responds with a message 'Missing input parameters'.
var message = JSON.stringify({
"urls": [
{
"long_url": "http://example.com",
}
]
});
var https_options = {
host: 'tinycc.com',
path: '/tiny/api/3/urls/',
port: 443,
method: 'POST',
headers: {
'Authorization': 'Basic XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
'Content-Length': message.length
}
}
var req = https.request(https_options,res => {
var msg = '';
res.on('data',d => msg += d);
res.on('end',() => {
console.log('end',JSON.parse(msg));
});
});
req.on('error',e => console.log('tinyURL error',e));
req.write(message);
req.end();
The response is always
{
error: {
code: 1305,
message: 'Missing input parameters',
details: ''
},
version: '3.1'
}
I don't know which library are you using for making the API call, but I think you will be better using request and including your payload as the body on your post request rather than using the more manual method of writing to the request.
var message = {
"urls": [
{
"long_url": "http://example.com",
}
]
};
var options = {
host: 'tinycc.com',
path: '/tiny/api/3/urls/',
port: 443,
method: 'POST',
body: message,
json: true,
headers: {
'Authorization': 'Basic XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
'Content-Length': message.length,
"Content-Type": "application/json"
}
}
request(options, console.log)
I am trying below javascript code to subscribe on mailchimp. flow wise working good but i am getting error like not authorize because may be i am not passing api key correctly. please help to solve my issue
var request = new Request('https://<dc>.api.mailchimp.com/3.0/lists/[listid]/members', {
method: 'POST',
mode: 'no-cors',
json: {
"email_address": "am_it#live.com",
"status": "subscribed",
},
redirect: 'follow',
headers: new Headers({
'Content-Type': 'application/json',
'Authorization': 'Basic apikey'
})
});
// Now use it!
fetch(request).then(function (data) {
console.log(data);
});
You need to add your authentification details with your username and api key. You can do it with the auth parameter:
auth: {
'user': 'yourUserName',
'pass': 'yourApiKey'
}
Just add that to your request object:
Request('https://<dc>.api.mailchimp.com/3.0/lists/[listid]/members', {
method: 'POST',
mode: 'no-cors',
json: {
"email_address": "am_it#live.com",
"status": "subscribed",
},
redirect: 'follow',
headers: new Headers({
'Content-Type': 'application/json',
'Authorization': 'Basic apikey'
}),
auth: {
'user': 'yourUserName',
'pass': 'yourApiKey'
}
});
I looked at the documentation in the getting started section of the developer mailchimp api: here and I converted the curl examples to javascript code using this page. Let me know if it worked.