NodeJS Patreon API account link - node.js

I'm trying to connect user accounts on my website to patreon. I keep getting an access_denied error message in response to step 3. I'm following this documentation.
My node server code looks like this:
socket.on("patreon_register",function(code,user){
var reqString = "api.patreon.com/oauth2/token?code="
+code
+"&grant_type=authorization_code&client_id="
+settings.patreon.Client_ID
+"&client_secret="
+settings.patreon.Client_Secret
+"&redirect_uri="
+"http%3A%2F%2Fwww.levisinger.com%2F%3Fpage%3Dpatreon_success",
req = querystring.stringify({
"code": code,
"grant_type": "authorization_code",
"client_id": settings.patreon.Client_ID,
"client_secret": settings.patreon.Client_Secret,
"redirect_uri": "http%3A%2F%2Fwww.levisinger.com%2F%3Fpage%3Dpatreon_success"
}),
post_options = {
host: 'api.patreon.com',
port: '80',
path: '/oauth2/token',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(req)
}
};
// Set up the request
console.log(req);
var post_req = http.request(post_options, function(res) {
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log(chunk);
if(
chunk.access_token &&
chunk.refresh_token &&
chunk.expires_in &&
chunk.scope &&
chunk.token_type
){
Auth.linkPatreon(user,chunk,function(err,res){
if(err){ socket.emit('patreon_register',false,res); }
else { socket.emit('patreon_register',true,res); }
});
}
});
});
// post the data
post_req.write(req);
post_req.end();
});
The req variable that's actually sent to the server looks like this (changed my codes to generic values of course)
code=MY_RESPONSE_CODE&grant_type=authorization_code&client_id=MY_CLIENT_ID&client_secret=MY_CLIENT_SECRET&redirect_uri=MY_RESPONSE_URI
Any ideas?

In the end, my server looks like this and is working:
socket.on("patreon_register",function(code,user){
var req = querystring.stringify({
code: code,
grant_type: "authorization_code",
client_id: settings.patreon.Client_ID,
client_secret: settings.patreon.Client_Secret,
redirect_uri: settings.patreon.redirect_uri
}),
post_options = {
host: 'api.patreon.com',
port: '80',
path: '/oauth2/token',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(req)
}
};
// Set up the request
console.log(req);
var post_req = http.request(post_options, function(res) {
res.setEncoding('utf8');
res.on('data', function (chunk) {
chunk = JSON.parse(chunk);
console.log(chunk);
if(!chunk["error"]){
console.log("Linking!");
Auth.linkPatreon(user,chunk,function(err,res){
if(err){ socket.emit('patreon_register',false,res); }
else { socket.emit('patreon_register',true,res); }
console.log("Linked!");
});
}
});
});

Related

NodeJS request get return me html code instead of json

I'm trying to get get a json from a get request it's work in python but in NodeJs that display me the html code source of the page
this is my code :
app.get("/well", function(request, response) {
const req = require('request');
const options = {
url: 'https://swarmmanager.francecentral.cloudapp.azure.com:3000',
method: 'GET',
headers: {
'Accept': 'application/json',
},
agentOptions: {
ca: fs.readFileSync("public/IdaktoPKIRootCA.crt")
}
};
req(options, function(err, res, body) {
console.log(body);
});
});
and this is another version but same problem:
app.get("/well", function(request, response) {
g_CnieOidcAddr = 'https://swarmmanager.francecentral.cloudapp.azure.com:3000';
const options = {
hostname: 'swarmmanager.francecentral.cloudapp.azure.com',
port: 3000,
method: 'GET',
headers: {
'Accept': 'application/json',
},
ca: fs.readFileSync("public/IdaktoPKIRootCA.crt")
};
const req = https.request(options, (res) => {
console.log('statusCode:', res.statusCode);
console.log('headers:', res.headers);
res.on('data', (d) => {
process.stdout.write(d);
});
});
req.on('error', (e) => {
console.error(e);
});
req.end();
});
i try to do it in python and it's work find that return me a json:
headers = {'Accept': 'application/json'}
r = requests.get(g_CnieOidcAddr + '/.well-known/openid-configuration', params={}, headers = headers, verify='./IdaktoPKIRootCA.crt')
print (r.text)
if anyone has an idea i'm a taker ^^ thanks for reading.
ok that work find i just forgot something at the end of the url so if you come to this page the 2 codes work find to to a request

Issue in creating POST http.request with Node.js data are passed in FormValue instead of Body

i try to execute a http.request POST and my data are passed to FormValue and not in Body.
It's my first experiment in Node.js http calls so I apologize if the question is trivial.
I passed the call to a servere and i got the data at the end of the code.
function doHttpApiCall(session,callback) {
var http = require('http');
var isEndedOk;
var outValue = '';
var postData = JSON.stringify({
grant_type: 'client_credentials',
scope: 'OOB',
my_id: 'my_id_value'
});
var postOptions = {
host: 'dummyapisite.com',
path: '/t/litf9-1571295453/post',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': postData.length
}
};
// Set up the request
var post_req = http.request(postOptions, function(res) {
var statusCode = res.statusCode;
let error;
if (statusCode !== 200) {
error = new Error('Request Failed.\n' +
`Status Code: ${statusCode}`);
}
res.setEncoding('utf8');
let rawData = '';
res.on('data', (chunk) => { rawData += chunk; });
res.on('end', () => {
try {
const parsedData = rawData;
if (error) {
isEndedOk = false;
console.error(error.message);
console.error('Response Content=' + String(parsedData));
res.resume();
} else {
isEndedOk = true;
console.log('Response Content=' + String(parsedData));
}
callback(session.attributes,
callBack_doHttpApiCall(outValue, statusCode, session, callback, isEndedOk));
} catch (e) {
console.error(e.message);
}
});
}).on('error', (e) => {
console.error(`Got error: ${e.message}`);
});
post_req.write(postData);
post_req.end();
}
this is the result got by the server and the data are not in the right place.
{
"Timestamp":"2019-10-17T13:53:52.941575Z",
"Method":"POST",
"RemoteAddr":"34.245.148.80",
"ID":390940052,
"Headers":{
"Content-Length":[
"118"
],
"Content-Type":[
"application/x-www-form-urlencoded"
],
"Host":[
"ptsv2.com"
],
"X-Cloud-Trace-Context":[
"deff20a349bfb409fab118aa361ebc54/925376340939905763"
],
"X-Google-Apps-Metadata":[
"domain=gmail.com,host=dummyapisite.com"
]
},
"FormValues":{
"{\"body\":[{\"grant_type\":\"client_credentials\",\"scope\":\"OOB\",\"my_id\":\"my_id_value\"}]}":[
""
]
},
"Body":"",
"Files":null,
"MultipartValues":null
}
The problem is that you're sending a JSON body, but the Content-Type you're sending is: application/x-www-form-urlencoded, so change it to application/json
The server you're posting to, is putting the value in FormValues because you're telling them that you're sending a form (x-www-form-urlencoded)
var postOptions = {
host: 'dummyapisite.com',
path: '/t/litf9-1571295453/post',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': postData.length
}
};

HTTP Module to Request Module Translation

How to rewrite this node.js code, just using the request module not http module?
var options = {
url: 'https://dnxr7vm27d.execute-api.us-east-1.amazonaws.com/prod/GetRewardInfo',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': 'kE2xi2OgUa7jfijmsd0jQ74aJntJwUEW2EU8LUsi'
}
};
var req = http.request(options, function(res) {
console.log('Status:' + res.statusCode);
console.log('Headers: ' + JSON.stringify(res.headers));
res.on('data', function(body) {
console.log('Body:' + body);
});
});
req.write('{"x-api-key":"12345", "Content-Type":"application/json", "appId":"DEMO1","momentId":"GAME_COMPLETE","deviceType":'
Android ','
campaignId ':"DEMOCAMP1","rewardGroupId":"amz1yprime"}');
req.end();
I've done part of it:
const request = require('request');
const data = JSON.stringify({
"appId": "DEMO1",
"momentId": "GAME_COMPLETE",
"deviceType": 'Android ',
'campaignId ': "DEMOCAMP1",
"rewardGroupId": "amz1yprime"
})
const options = {
url: 'https://dnxr7vm27d.execute-api.us-east-1.amazonaws.com/prod/GetReward',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': 'kE2xi2OgUa7jfijmsd0jQ74aJntJwUEW2EU8LUsi'
},
};
request.post(options, function(err, res, body) {
console.log(body);
});
But i don't know how to send "data" and how to get a response to the request
The re-write is not drastic. It's some few simple change.
const request = require('request')
var options = {
url: 'https://dnxr7vm27d.execute-api.us-east-1.amazonaws.com/prod/GetRewardInfo',
method: 'POST',
headers: {
'Content-Type': 'application/json; charset=UTF-8',
'x-api-key': 'kE2xi2OgUa7jfijmsd0jQ74aJntJwUEW2EU8LUsi'
},
body: {
'appId': 'DEMO1',
'momentId':'GAME_COMPLETE',
'deviceType' : 'Android',
'campaignId' : 'DEMOCAMP1',
'rewardGroupId': 'amz1yprime'
},
json: true // sets body to JSON representation of value
};
request.post(options, (err, httpResponse, body) => {
if (err) console.error(err);
// httpResponse contains the full response object, httpResponse.statusCode etc
else console.log(body);
})

How do you make this curl request in node

This curl request to the spotify API works perfectly fine
curl -X "POST" -H "Authorization: Basic <my-key-here>" -d grant_type=client_credentials https://accounts.spotify.com/api/token
I'm trying to do this in node, but it's not working and returns a 400 Bad Request. Here is my code. What am I doing wrong?
function AuthRequest(key) {
const req_body_params = JSON.stringify({
grant_type: "client_credentials"
})
const base64_enc = new Buffer(key).toString("base64")
const options = {
host: "accounts.spotify.com",
port: 443,
path: "api/token",
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Basic ${base64_enc}`
}
}
const req = https.request(options, function (res) {
res.on('data', function (data) {
alert("success: " + data)
})
})
req.on('error', function (err) {
alert("error: " + err)
})
req.write(req_body_params)
req.end()
}
I'm trying to use the Client Credentials method as explained here: https://developer.spotify.com/web-api/authorization-guide/
The request should be in application/x-www-form-urlencoded instead of JSON, it should be const req_body_params = "grant_type=client_credentials" with a header of "Content-Type": "application/x-www-form-urlencoded"
function AuthRequest(key) {
const req_body_params = "grant_type=client_credentials";
const base64_enc = new Buffer(key).toString("base64");
const options = {
host: "accounts.spotify.com",
port: 443,
path: "/api/token",
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"Authorization": `Basic ${base64_enc}`
}
};
const req = https.request(options, function(res) {
res.on('data', function(data) {
alert("success: " + data)
})
});
req.on('error', function(err) {
alert("error: " + err)
});
req.write(req_body_params);
req.end();
}
Because token expires is good to request them dynamically, I created a method that output a token as a promise, then you can consume in your request.
const axios = require('axios')
const client_id = process.env.SPOTIFY_CLIENT_ID;
const client_secret = process.env.SPOTIFY_CLIENT_SECRET;
function getToken( ) {
return axios({
url: 'https://accounts.spotify.com/api/token',
method: 'post',
params: {
grant_type: 'client_credentials'
},
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
auth: {
username: client_id,
password: client_secret
}
})
}
async function getSpotifyData( endpoint ){
const tokenData = await getToken( );
const token = tokenData.data.access_token;
axios({
url: `https://api.spotify.com/v1/${endpoint}`,
method: 'get',
headers: {
'Authorization': 'Bearer ' + token
}
}).then( response => {
console.log( response.data );
return response.data;
}).catch( error => {
throw new Error(error);
});
}
getSpotifyData( 'browse/new-releases' );

Why can't I POST data using Express?

var locationJSON, locationRequest;
locationJSON = {
latitude: 'mylat',
longitude: 'mylng'
};
locationRequest = {
host: 'localhost',
port: 1234,
path: '/',
method: 'POST',
header: {
'content-type': 'application/x-www-form-urlencoded',
'content-length': locationJSON.length
}
};
var req;
req = http.request(options, function(res) {
var body;
body = '';
res.on('data', function(chunk) {
body += chunk;
});
return res.on('end', function() {
console.log(body);
callback(null, body);
});
});
req.on('error', function(err) {
callback(err);
});
req.write(data);
req.end();
On the other end, I have a node.js server listening to port 1234 and it never gets the request. Any ideas?
You are doing req.write(data) but as far as I can see 'data' is not defined anywhere. You are also setting the 'content-length' header to locationJSON.length, which is undefined because locationJSON only has 'latitude' and 'longitude' properties.
Properly define 'data', and change the 'content-type' and 'content-length' to use that instead.
var locationJSON, locationRequest;
locationJSON = {
latitude: 'mylat',
longitude: 'mylng'
};
// convert the arguments to a string
var data = JSON.stringify(locationJSON);
locationRequest = {
host: 'localhost',
port: 1234,
path: '/',
method: 'POST',
header: {
'content-type': 'application/json', // Set the content-type to JSON
'content-length': data.length // Use proper string as length
}
};
/*
....
*/
req.write(data, 'utf8'); // Specify proper encoding for string
req.end();
Let me know if this still doesn't work.

Resources