Making a x-www-form-urlencoded request with axios - javascript

const { user } = require('./config');
const axios = require('axios');
const Querystring = require('querystring');
let body = Querystring['stringify']({
email: 'MY EMAIL#email.com',
password: 'pass'
})
const config = {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}
axios['post']('https://minecraftservers.org/login', body, config)
['then'](response => console.log(response))
Im trying to login through a website
it doesn't have an api
the headers are correct
if you're wandering how i knew this, i used chrome dev tools
like reverse engineer
content-type: application/x-www-form-urlencoded
that's the header they used when i tried to login to the site
this is what i get when i logged in through the site and not the code, it works there.

You can use URLSearchParams
const params = new URLSearchParams();
params.append('firstName', 'paul');
params.append('lastName', 'fred');
axios.post('/user', params);
It avoids adding another library.

I guess systax is your problem. Do you have any difficulties other than the syntax?
const { user } = require('./config');
const axios = require('axios');
const Querystring = require('querystring');
let body = Querystring['stringify']({
email: 'MY EMAIL#email.com',
password: 'pass'
})
const config = {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}
axios.post('https://minecraftservers.org/login', body, config)
.then(response => console.log(response))

Try
axios.post('https://minecraftservers.org/login', body, config)
.then(response => console.log(response))

Related

Bad respond when trying to get authentication token for Reddit api 'Application Only OAuth'

So i been trying to get access to the reddit api.
I registered to reddit. verified my mail. opened an app and got my credentials.
Followed this official documentation and also came across to this tutorial
All my efforts have failed and don't get any respond.
I am using nodejs. but also tried in postman and failed.
Tried 2 options using fetch and using axios:
const axios = require('axios');
const fetch = require('node-fetch')
const { URLSearchParams } = require('url')
class RedditApi {
clientId2 = "get ur own credentials by opening an app here https://www.reddit.com/prefs/apps";
clientSecret2 = "get ur own credentials by opening an app here https://www.reddit.com/prefs/apps";
authenticationUrl = `https://www.reddit.com/api/v1/access_token`;
BASE_URL = 'https://www.reddit.com/';
tokenAuth = null;
tokenExpirationTime = null;
currencyObj = null;
constructor(currencyObj) {
this.currencyObj = currencyObj;
console.log("constructor service")
}
async getAuthToken() {
const bodyParams = new URLSearchParams({
grant_type: "https://oauth.reddit.com/grants/installed_client",
device_id: "DO_NOT_TRACK_THIS_DEVICE"
});
console.log(this.clientId2, 'this.clientId');
debugger;
const headersObj = {
'Authorization': `Basic ${Buffer.from(`${this.clientId2}:`).toString('base64')}`,
'Content-Type': 'application/x-www-form-urlencoded',
};
let response = null;
try {
response = await axios.post(this.authenticationUrl,
bodyParams,
{
headers: headersObj
});
debugger;
} catch (error) {
debugger;
console.error(error);
console.log(error.stack);
return null;
}
}
async getAuthToken2() {
try {
// Creating Body for the POST request which are URL encoded
const params = new URLSearchParams()
params.append('grant_type', 'https://www.reddit.com/api/v1/access_token')
params.append('device_id', 'DO_NOT_TRACK_THIS_DEVICE')
// Trigger POST to get the access token
const tokenData = await fetch('https://oauth.reddit.com/grants/installed_client', {
method: 'POST',
body: params,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': `Basic ${Buffer.from(`${this.clientId2}:`).toString('base64')}` // Put password as empty
}
}).then(res => {
debugger;
return res.text()
})
debugger;
if (!tokenData.error) {
debugger;
res.send(trendingResult)
}
res.status(tokenData.error).send(tokenData.message)
} catch (error) {
debugger;
console.log(error)
}
}
}
module.exports = RedditApi;
when using axios i get this respond: "Request failed with status code 401"
When using fetch i get this respond: "'403 Forbidden\nRequest forbidden by administrative rules.\n\n'"
Anybody knows what is the problem and how can i fix it?
Many thanks!

How to send Base64 to API

I am ultimately trying to send a fax with the Vitelity API. I have an API on EC2 that I am calling from my React Native app:
// Encoding to Base64
const encodeB64 = () => {
RNFS.readFile(croppedImage, 'base64').then(res => {
sendB64(res);
});
};
const sendB64 = b64 => {
let myHeaders = new Headers();
myHeaders.append('Content-Type', 'application/json');
let raw = JSON.stringify({
data1: b64, // 'jdl3439fdjsle/jjug'
login: {login},
pass: {pass},
faxnum: {destinationNum},
faxsrc: {sourceNum},
recname: 'Test',
file1: 'testfax.jpg',
});
let requestOptions = {
method: 'POST',
headers: myHeaders,
body: raw,
redirect: 'follow',
};
fetch(API_URL, requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
};
However, this returns an error cannot POST. If, instead of b64, I change data1's value to something like jdl3439fdjsle/jjug, everything is great.
Do I need to do something special to b64 before I can send it?
My Base64 looks like: /9j/4AA{1.2m more chars}uB//9k=. I've pasted it into a converter and it produces the correct image.
I geuss you have to use a Multipart Form with multipart/form-data as content-type headers if you want to send images. See also this question.

node.js oauth-1.0a working for Twitter API v1.1 but not for v2

I've found this function to generate oauth-1.0a header:
// auth.js
const crypto = require("crypto");
const OAuth1a = require("oauth-1.0a");
function auth(request) {
const oauth = new OAuth1a({
consumer: {
key: process.env.TWITTER_API_KEY,
secret: process.env.TWITTER_API_SECRET_KEY,
},
signature_method: "HMAC-SHA1",
hash_function(baseString, key) {
return crypto.createHmac("sha1", key).update(baseString).digest("base64");
},
});
const authorization = oauth.authorize(request, {
key: process.env.TWITTER_ACCESS_TOKEN,
secret: process.env.TWITTER_ACCESS_TOKEN_SECRET,
});
return oauth.toHeader(authorization).Authorization;
}
module.exports = auth;
It works fine if I try it with Twitter API v1.1:
// v1.js
require("dotenv").config();
const axios = require("axios");
const auth = require("./auth");
const url = "https://api.twitter.com/1.1/favorites/create.json";
const method = "POST";
const params = new URLSearchParams({
id: "1397568983931392004",
});
axios
.post(url, undefined, {
params,
headers: {
authorization: auth({
method,
url: `${url}?${params}`,
}),
},
})
.then((data) => {
return console.log(data);
})
.catch((err) => {
if (err.response) {
return console.log(err.response);
}
console.log(err);
});
But if I try it with Twitter API v2:
// v2.js
require("dotenv").config();
const axios = require("axios");
const auth = require("./auth");
const url = `https://api.twitter.com/2/users/${process.env.TWITTER_USER_ID}/likes`;
const method = "POST";
const data = {
tweet_id: "1397568983931392004",
};
axios
.post(url, data, {
headers: {
authorization: auth({
method,
url,
data,
}),
},
})
.then((data) => {
return console.log(data);
})
.catch((err) => {
if (err.response) {
return console.log(err.response);
}
console.log(err);
});
it fails with:
{
title: 'Unauthorized',
type: 'about:blank',
status: 401,
detail: 'Unauthorized'
}
I tried encoding the body of the request as suggested here, but get the same error:
require("dotenv").config();
const axios = require("axios");
const auth = require("./auth");
const querystring = require("querystring");
const url = `https://api.twitter.com/2/users/${process.env.TWITTER_USER_ID}/likes`;
const method = "POST";
const data = percentEncode(
querystring.stringify({
tweet_id: "1397568983931392004",
})
);
function percentEncode(string) {
return string
.replace(/!/g, "%21")
.replace(/\*/g, "%2A")
.replace(/'/g, "%27")
.replace(/\(/g, "%28")
.replace(/\)/g, "%29");
}
axios
.post(url, data, {
headers: {
"content-type": "application/json",
authorization: auth({
method,
url,
data,
}),
},
})
.then((data) => {
return console.log(data);
})
.catch((err) => {
if (err.response) {
return console.log(err.response);
}
console.log(err);
});
If tested with Postman, both endpoints (1.1 and 2) work fine with the same credentials.
Any ideas on what am I doing wrong while using v2 or how to get it working with Twitter API v2?
I suspect it's something related with the body of the request as that's the main diference between both requests, but haven't been able to make it work.
Figure it out, the body of the request should not be included while generating the authorization header:
require("dotenv").config();
const axios = require("axios");
const auth = require("./auth");
const url = `https://api.twitter.com/2/users/${process.env.TWITTER_USER_ID}/likes`;
const method = "POST";
const data = {
tweet_id: "1397568983931392004",
};
axios
.post(url, data, {
headers: {
authorization: auth({
method,
url,
}),
},
})
.then((data) => {
return console.log(data);
})
.catch((err) => {
if (err.response) {
return console.log(err.response);
}
console.log(err);
});
Basically, when making a post request to Twitter API v1.1, the data should be encoded, should be used to generate the authorization header, and the post request should be sent as application/x-www-form-urlencoded.
When making a post request to Twitter API v2, the data should not be encoded, should not be included while generating the authorization header, and must be sent as application/json.
Hope this becomes helpful to someone else.

jwt token return null

i try to get a user id by token,
the token is pass by the header Authorization,
when i use ExtractJwt.fromAuthHeaderWithScheme("jwt")(req)
i get back the token as null
here is pass the token to the header.
const token = localStorage.getItem("id_token");
export const insertMovie = (payload) => {
return api.post(`/movie`, payload, {
headers: { "Authorization": `${token}` },
});
};
here i try to verify to token
var User = require("../models/user-model");
var Movie = require("../models/movie-model");
var bcrypt = require("bcrypt");
var jsonwt = require("jsonwebtoken");
var key = require("../db/myUrl");
var ExtractJwt = require("passport-jwt");
createMovie = async (req, res) => {
const movieDetails = req.body.movie;
const token = ExtractJwt.ExtractJwt.fromAuthHeaderWithScheme("jwt")(req);
const decoded = jsonwt.verify(token, key.secret);
const userId = decoded.userId;
console.log(decoded);
}
When you try to
ExtractJwt.fromAuthHeaderWithScheme("jwt")
you need to add the token to the header like so:
headers: { "Authorization": `jwt ${token}` },
from the docs:
fromAuthHeaderWithScheme(auth_scheme) creates a new extractor that looks for the JWT in the authorization header, expecting the scheme to match auth_scheme.
You’ve doubled up ExtractJwt but also if you’re declaring a scheme “jwt” that needs to be appended to the token
headers: { Authorization: `jwt ${token}` }
Otherwise change fromAuthHeaderWithScheme to just fromAuthHeader to fromHeader(‘Authorization')
Also I’m not sure if you can use passport directly inside an endpoint like this - I always thought it needed to be used as middleware.

Firebase cloud function with fetch request with basic auth to external api

I seem to be having an issue with getting the expected response from a fetch call within a firebase cloud function. I'm sure it's due to my lack of knowledge on how the responses, promises, etc. work.
I'm trying to use atlassian crowd's rest api for SSO. If I use postman, I can get the desired results from the request. So I know that part of it is working.
What led me to using a cloud function is that making the same request using fetch was resulting in CORS issues from localhost. I figured if I can take the browser out of the equation, then the CORS issues would disappear. Which they have, but I'm not getting the desired response.
My cloud function looks like this:
const functions = require('firebase-functions');
const fetch = require('node-fetch');
const btoa = require('btoa');
const cors = require('cors')({origin:true});
const app_name = "app_name";
const app_pass = "app_password";
exports.crowdAuthentication = functions.https.onRequest((request, response)=>
{
cors(request, response, () =>{
let _uri = "https://my.server.uri/crowd/rest/usermanagement/1/session";
let _headers = {
'Content-Type':'application/json',
'Authorization':`Basic ${btoa(`${app_name}:${app_pass}`)}`
}
let _body = {
username: request.body.username,
password: request.body.password
}
const result = fetch(_uri, {
method: 'POST',
headers: _headers,
body: JSON.stringify(_body),
credentials: 'include'
})
response.send(result);
})
})
I'm then making the call in my application using fetch to the firebase endpoint and passing the username/password:
fetch('https://my.firebase.endpoint/functionName',{
method: 'POST',
body: JSON.stringify({username:"myusername",password:"mypassword"}),
headers: {
'Content-Type':'application/json'
}
})
// get the json from the readable stream
.then((res)=>{return res.json();})
// log the response - {size:0, timeout:0}
.then((res)=>
{
console.log('response: ',res)
})
.catch(err=>
{
console.log('error: ',err)
})
Thanks for looking.
Edit of May 2020
Note that request-promise is deprecated and I recommend to use axios.
Update following our discussion in the comments below
It appears that it doesn't work with the node-fetch library and that you should use another library like request-promise.
Therefore you should adapt your code as follows:
//......
var rp = require('request-promise');
exports.crowdAuthentication = functions.https.onRequest((request, response) => {
cors(request, response, () => {
let _uri = "https://my.server.uri/crowd/rest/usermanagement/1/session";
let _headers = {
'Content-Type': 'application/json',
'Authorization': `Basic ${btoa(`${app_name}:${app_pass}`)}`
}
let _body = {
username: request.body.username,
password: request.body.password
}
var options = {
method: 'POST',
uri: _uri,
body: _body,
headers: _headers,
json: true
};
rp(options)
.then(parsedBody => {
response.send(parsedBody);
})
.catch(err => {
response.status(500).send(err)
//.... Please refer to the following official video: https://www.youtube.com/watch?v=7IkUgCLr5oA&t=1s&list=PLl-K7zZEsYLkPZHe41m4jfAxUi0JjLgSM&index=3
});
});
});
Initial answer with node-fetch
The fetch() method is asynchronous and returns a Promise. You therefore need to wait this Promise resolves before sending back the response, as follows:
exports.crowdAuthentication = functions.https.onRequest((request, response)=>
{
cors(request, response, () =>{
let _uri = "https://my.server.uri/crowd/rest/usermanagement/1/session";
let _headers = {
'Content-Type':'application/json',
'Authorization':`Basic ${btoa(`${app_name}:${app_pass}`)}`
}
let _body = {
username: request.body.username,
password: request.body.password
}
fetch(_uri, {
method: 'POST',
headers: _headers,
body: JSON.stringify(_body),
credentials: 'include'
})
.then(res => {
res.json()
})
.then(json => {
response.send(json);
}
.catch(error => {
//.... Please refer to the following official video: https://www.youtube.com/watch?v=7IkUgCLr5oA&t=1s&list=PLl-K7zZEsYLkPZHe41m4jfAxUi0JjLgSM&index=3
});
})
})
In addition, note that you need to be on the "Flame" or "Blaze" pricing plan.
As a matter of fact, the free "Spark" plan "allows outbound network requests only to Google-owned services". See https://firebase.google.com/pricing/ (hover your mouse on the question mark situated after the "Cloud Functions" title)

Categories