I'm trying to post data to the mediawiki API and it's not recognising the token I am sending.
var data = querystring.stringify({
action: "createaccount",
name: "sean",
email: "xxx",
password: "test",
token: "66cde5ad831521fe9d0fe4df3a2db25f"
});
var options = {
host: '54.201.91.132',
port: 80,
path: '/wiki/api.php',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(data)
}
};
var req = http.request(options, function(res) {
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log("body: " + chunk);
});
});
req.write(data);
req.end();
I have tried sending the same data using the Postman chrome extension and this works fine.
POST /wiki/api.php HTTP/1.1
Host: 54.201.91.132
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded
action=createaccount&name=shamus&email=xxx&password=test&token=5dc9c943ac3255f87dc7782c24f61ac6&format=json
{
"createaccount": {
"username": "Shamus",
"userid": 22,
"token": "c3744c0f19ea62f6baf89b10f7c86f7f",
"result": "success"
}
}
Any ideas what I'm doing wrong?
In addition to token, you must pass it the cookies you received with it. Of course, the token must not be hardcoded and be acquired dynamically.
Related
Hello I have tried to use the instagram api to get a connection token. I first tested it on postman and this is what I did:
I used this link to make a request post to the instagram api:
https://api.instagram.com/oauth/access_token?client_id=clientid&client_secret=clientsecret&grant_type=authorization_code&redirect_uri=https://mysite/&code=thecode
The api gives me an error: Missing required field client_id
But when I set the content type to x-www-form-urlencoded everything works fine on postman.
So I tried to do the same thing in javascript with the node module request. I tried to do the same thing as on postman with the module but it does not work... Here is my code:
request(`https://api.instagram.com/oauth/access_token?client_id=clientid&client_secret=clientsecret&grant_type=authorization_code&redirect_uri=https://mysite/&code=` + code, {
method: 'POST',
headers: {"Content-Type": "x-www-form-urlencoded"}
}, (error, response, body) => {
console.log('body:', body)
})
As per MDN, the content type should be application/x-www-form-urlencoded
https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST
Update:
You should read the node doc : https://nodejs.dev/learn/making-http-requests-with-nodejs
Get method:
const https = require('https');
const options = {
hostname: 'api.instagram.com',
path: '/oauth/access_token?client_id=clientid&client_secret=clientsecret&grant_type=authorization_code&redirect_uri=https://mysite/&code=thecode',
method: 'GET',
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"Accept": "Accept-Encoding"
}
};
const req = https.request(options, (res) => {
// ...
});
Post method:
var headers = {
"Content-Type": "application/x-www-form-urlencoded",
"Accept": "Accept-Encoding"
};
var options = {
url: 'https://api.instagram.com/oauth/access_token',
method: 'POST',
headers: headers
};
var form = {
grant_type:'urn:ietf:params:oauth:grant-type:jwt-bearer',
client_id: 'id',
client_secret: 'secret'
redirect_uri : 'https://mysite/&code=thecode'
};
var request = https.request(options, function(response) {
// do stuff
});
request.write(querystring.stringify(form));
request.end();
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 to make a POST request to Expo's servers using the request library for JS.
Expo requires that certain headers be added, and so I went ahead and added them in a dictionary called headers.
expoPushURL = "https://exp.host/--/api/v2/push/send";
headers = {
"accept": "application/json",
"accept-encoding": "gzip, deflate",
"content-type": "application/json"
};
data = JSON.stringify({
"to": "ExponentPushToken[myDeviceToken]",
"sound": "default",
"title": "hello",
"body": "Hello world!"
});
options = {
url: expoPushURL,
headers: headers,
method: "POST",
body: data,
json: true
};
request(options, function (error, response, body) {
console.log("Response from request: ",response);
console.log("Error from request: ", error);
});
The callback is returning an undefined object. The request module has been imported without any problems. What am I doing wrong?
I am getting this error message:
Error from request: { Error: getaddrinfo ENOTFOUND exp.host exp.host:443
at errnoException (dns.js:28:10)
at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:76:26)
code: 'ENOTFOUND',
errno: 'ENOTFOUND',
syscall: 'getaddrinfo',
hostname: 'exp.host',
host: 'exp.host',
port: 443 }
These "settings" or parameters work perfectly fine when I use curl or Python's requests library, but I need this solution to be in JS. With that said, I am sure that means there is something wrong with my code.
EDIT: The related curl would look like this:
curl -H "Content-Type: application/json" -X POST https://exp.host/--/api/v2/push/send -d '{
"to": "ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]",
"title":"hello",
"body": "world"
}'
You do not have problem with headers, they are working correctly, something else is missing. What is your curl?
I have run your code against my dummy server, which returns in body all interesting values that he accepted. With this code
const expoPushURL = "http://localhost:3099";
const headers = {
"accept": "application/json",
"accept-encoding": "gzip, deflate",
"content-type": "application/json"
};
const data = JSON.stringify({
"to": "ExponentPushToken[myDeviceToken]",
"sound": "default",
"title": "hello",
"body": "Hello world!"
});
const options = {
url: expoPushURL,
headers: headers,
method: "POST",
body: data,
json: true
};
import * as request from 'request';
request(options, function (error, response, body) {
console.log(body.received);
});
I got this response
{ body: '"{\\"to\\":\\"ExponentPushToken[myDeviceToken]\\",\\"sound\\":\\"default\\",\\"title\\":\\"hello\\",\\"body\\":\\"Hello world!\\"}"',
method: 'POST',
headers:
{ accept: 'application/json',
'accept-encoding': 'gzip, deflate',
'content-type': 'application/json',
host: 'localhost:3099',
'content-length': '115',
connection: 'close' },
url: '/' }
If someone would be just interested, the server I am using is having this code
const http = require('http');
const _ = require('lodash');
http.createServer((request, response) => {
const { headers, method, url } = request;
let body = [];
request.on('error', (err) => {
console.error(err);
}).on('data', (chunk) => {
body.push(chunk);
}).on('end', () => {
body = Buffer.concat(body).toString();
let bodyToSend = JSON.stringify({
alwaysHere: 'Always here',
received: {
body,
method,
headers,
url,
}
});
if (body) {
body = JSON.parse(body);
if (body && _.isObject(body.control)) {
const control = body.control;
if (_.isNumber(control.statusCode)) {
response.statusCode = control.statusCode;
}
if (_.isArray(control.headers)) {
control.headers.forEach(header => {
response.setHeader(header.name, header.value);
});
}
if (_.isString(control.body)) {
bodyToSend = control.body;
}
}
}
if (!response.hasHeader('content-type')) {
response.setHeader('Content-Type', 'application/json');
}
response.write(bodyToSend); // write a response to the client
response.end(); // end the response
});
}).listen(3099);
I'm just beginning to learn javascript and https requests. I'm working in Visual Studio 2017, I created a blank javascript console app from the template and added the following code.
const https = require('https');
const options = {
hostname: 'api.gdax.com',
path: '/products/BTC-USD/stats',
method: 'GET',
agent: false
};
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();
The response I get from the server is
{"message":"User-Agent header is required."}
When I navigate to https://api.gdax.com/products/BTC-USD/stats in my browser I get the correct response. How come I can't do the same in a javascript console?
That's because that specific API is blocking any request without the User-Agent header.
Just add the header, and it will work fine:
const https = require('https');
const options = {
hostname: 'api.gdax.com',
path: '/products/BTC-USD/stats',
method: 'GET',
agent: false,
headers: {
'User-Agent': 'something',
},
};
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();
You need to set headers manually. See http documentation for all possible request options (this is the same for http and https).
try:
const options = {
hostname: 'api.gdax.com',
path: '/products/BTC-USD/stats',
method: 'GET',
agent: false,
headers: {
'User-Agent': 'Foo/1.0',
},
};
You need to explicitely set the User-Agent header in the headers property of your request options
const options = {
hostname: 'api.gdax.com',
path: '/products/BTC-USD/stats',
method: 'GET',
agent: false,
headers: { 'User-Agent': 'Mosaic/1.0' }
};
I have a command-line script written in JavaScript which needs to connect to a REST Api on a remote SharePoint site, but I cannot figure out how to authenticate. I can log on in a browser using forms authentication, and by inspecting the request I should be able to reproduce it in node.js to get the appropriate auth cookie or token. However, I actually get a 403 Forbidden. I don't know if this is the best way of doing it, but I can't find very much info on it. Here is my script:
var http = require('http');
var querystring = require('querystring');
var postData = querystring.stringify({
'ctl00$PlaceHolderMain$signInControl$UserName': 'restapi',
'ctl00$PlaceHolderMain$signInControl$password': 'my_password',
'ctl00$PlaceHolderMain$signInControl$login': 'Sign In'
});
var options = {
hostname: 'sharepoint.example.com',
port: 80,
path: '/_layouts/15/Authenticate.aspx?Source=%2F',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': postData.length
}
};
var req = http.request(options, function(res) {
console.log('STATUS: ' + res.statusCode);
console.log('HEADERS: ', res.headers);
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log('BODY: ' + chunk);
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
// write data to request body
req.write(postData);
req.end();
And the response headers are:
{ 'cache-control': 'private',
'content-type': 'text/plain; charset=utf-8',
server: 'Microsoft-IIS/8.5',
'x-sharepointhealthscore': '0',
'x-aspnet-version': '4.0.30319',
sprequestguid: '366d149d-79af-b07c-1764-dec7001b46a2',
'request-id': '366d149d-79af-b07c-1764-dec7001b46a2',
'x-frame-options': 'SAMEORIGIN',
sprequestduration: '7',
spiislatency: '0',
'x-forms_based_auth_required': 'http://sharepoint.example.com/_login/default.aspx?ReturnUrl=/_layouts/15/error.aspx&Source=%2f_layouts%2f15%2fAuthenticate.aspx%3fSource%3d%252F',
'x-forms_based_auth_return_url': 'http://sharepoint.example.com/_layouts/15/error.aspx',
'x-msdavext_error': '917656; Access denied. Before opening files in this location, you must first browse to the web site and select the option to login automatically.',
'x-powered-by': 'ASP.NET',
microsoftsharepointteamservices: '15.0.0.4569',
'x-content-type-options': 'nosniff',
'x-ms-invokeapp': '1; RequireReadOnly',
date: 'Sat, 27 Jun 2015 10:53:28 GMT',
connection: 'close',
'content-length': '13' }
Any suggestions?
Are you sure that REST API allows CORS? because a 403 Forbidden might mean that you are not allowed to contact that endpoint from outside.
Does that remote SharePoint app use AD for authentication?
if so you might need to check this package https://www.npmjs.com/package/activedirectory