Axios and Oauth1.0 - 'status: 400, Bad Request' - node.js

I'm new on Nodejs and all the modules related with Node. I've been trying to use axios for send a Oauth1.0 Autorization signature, but i'm getting: response: { status: 400, statusText: 'Bad Request', ...}
import { BASE_URL } from '../../../config/config.js';
import axios from 'axios';
import status from 'http-status';
import OAuth from 'oauth-1.0a';
import { createHmac } from 'crypto';
import dotenv from 'dotenv';
dotenv.config();
const CONSUMERKEY = process.env.consumer_key;
const CONSUMERSECRET = process.env.consumer_secret;
const TOKENKEY = process.env.access_token;
const TOKENSECRET = process.env.token_secret;
export const oauth = OAuth({
consumer: {
key: CONSUMERKEY,
secret: CONSUMERSECRET,
},
signature_method: 'HMAC-SHA1',
hash_function(base_string, key) {
return createHmac('sha1', key)
.update(base_string)
.digest('base64')
},
})
export const token = {
key: TOKENKEY,
secret: TOKENSECRET,
}
const doRequest = async (query) => {
const request_data = {
url: `${BASE_URL}`,
method: 'GET',
params: { q: `${query}` },
};
const authHeader = oauth.toHeader(oauth.authorize(request_data, token));
return await axios.get(request_data.url, request_data.params, { headers: authHeader });
};
const searchU = async (term) => {
return await doRequest(`${term}`);
};
export const userS = async (req, res, next) => {
try {
const { query } = req;
const { data } = await searchU(query.q);
const string = JSON.stringify(data);
const Rs = JSON.parse(string);
const response = {
code: 1,
message: 'sucess',
response: Rs
};
res.status(status.OK).send(response);
} catch (error) {
next(error);
if (error.response){
console.log("Response: ");
console.log(error.response);
} else if(error.request){
console.log("Request: ");
console.log(error.request)
} else if(error.message){
console.log("Message: ");
console.log(error.message)
}
}
};
I've been also trying the solution given On this post: but there's no way I can make this work, no idea what i could be doing wron...
When i try the following code (see below), using Request module (which is deprecated) works well, but I really need to do it with Axios...
const request_data = {
url: `${BASE_URL}`,
method: 'GET',
params: { q: `${query}` },
};
const authHeader = oauth.toHeader(oauth.authorize(request_data, token));
request(
{
url: request_data.url,
method: request_data.method,
form: request_data.params,
headers: authHeader,
},
function(error, response, body) {
console.log(JSON.parse(body));
}
)
Any thoughts on what I'm doing wrong on this?? Thank you very much!!

Refer to the following link for the Request Config for Axios. I believe you need to have the query params after the header in the axios.get()
Axios Request Config
Try, the following and see how it goes:-
return await axios.get(request_data.url, { headers: authHeader }, request_data.params);

Related

how to set headers in axios patch request in react js

Can someone tell me what mistake I am making or tell me how to set the header in axios patch request. when I am running the API through postman, everything is working fine but when I connect it with the front end, an error comes up saying that the JWT is not provided on the backend
here is the frond end code :
import React, { useEffect } from 'react';
import { useParams } from 'react-router';
import axios from 'axios';
const Loader = () => {
const parmas = useParams();
const { id } = parmas;
console.log(id);
useEffect(() => {
const fetchBags = async () => {
try {
const res = await axios.patch('http://localhost:4001/public/verify', {
headers: {
'Content-Type': 'application/json',
Token: id,
},
});
console.log(res);
console.log('CBM', { res });
} catch (error) {
console.log(error);
}
};
fetchBags();
}, []);
return <div>this is loader</div>;
};
export default Loader;
below is my backend code:
export const verifyUser = async (data) => {
const token1 = data.header("Token");
try {
const verified = jwt.verify(token1, getTokenSecret());
console.log(verified)
await userModel.verifyUser(verified);
return {
message: "success",
};
} catch (error) {
console.log(`Auth Service > verifyUser > ${error.toString()}`);
throw error;
}
};
this error is comming:
Error
From docs
axios.patch(url[, data[, config]])
As you can see you pass config in 3rd argument not 2nd.
const res = await axios.patch(
'http://localhost:4001/public/verify',
{}, // data (2nd argument)
{
headers: {
'Content-Type': 'application/json',
Token: id,
},
} // config (3rd argument)
)

simple api with basic auth

I have:
const https = require('https');
const axios = require('axios');
exports.getEvents = async (req, res) => {
const httpsAgent = new https.Agent({
rejectUnauthorized: false,
});
try {
await axios.get('http://localhost/api/events',
{
httpsAgent,
auth: {
username: "senstar",
password: "senstar"
}
}).then(resp => {
res.json(resp.data);
});
} catch (error) {
console.error(error);
}
}
this's a simple api, I test http://localhost/api/events' on postman, using Authorization: Basic Auth and work it. So I implement the function getEvents to get the results on node js, but this's not working, why? what's wrong? with basic auth?
Try this code
const https = require('https');
const axios = require('axios');
const base64 = require('base-64');
exports.getEvents = async (req, res) => {
try {
await axios.get('https://127.0.0.1/api/events',
{
headers: {
'Authorization': 'Basic ' + base64.encode("senstar" + ":" + "senstar")
}
}).then(resp => {
res.json(resp.data);
});
} catch (error) {
console.error(error);
}
}

Keep getting pending request when trying to call endpoint, what's wrong?

I have made an endpoint to get token for paytm payment integration. In backend when i'm calling api i'm getting reqdata json but in frontend when i'm logging await transactionAPI, i'm getting only pending promise. i've tried using then in backend in PaytmChecksum.generateSignature method & in frontend in fetch but nothing is working. Keep getting the same result. Pls help.
Frontend code:
const makePayment = async () => {
const data = {
oid: String(new Date().valueOf()),
amount: '1.00',
email: 'abc#gmail.com',
};
let transactionAPI = fetch('http://localhost:3000/api/pretransact', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
});
console.log(await transactionAPI);
}
Backend code:
const https = require('https');
const PaytmChecksum = require('./PaytmChecksum');
export default async function handler(req, res) {
if (req.method == 'POST') {
const { oid, amount, email } = req.body;
let mid = process.env.PAYTM_MID;
let paytmParams = {};
paytmParams.body = {
requestType: 'Payment',
mid,
websiteName: process.env.WEBSITE,
orderId: oid,
callbackUrl: 'http://localhost:3000/api/callback',
txnAmount: {
value: amount,
currency: 'INR',
},
userInfo: {
custId: email,
},
};
const checksum = await PaytmChecksum.generateSignature(
JSON.stringify(paytmParams.body),
process.env.MERCHANT_KEY
);
paytmParams.head = {
signature: checksum,
};
var post_data = JSON.stringify(paytmParams);
const requestAsync = () => {
return new Promise((resolve, reject) => {
var options = {
hostname: 'securegw-stage.paytm.in',
// hostname: 'securegw.paytm.in',
port: 443,
path: `/theia/api/v1/initiateTransaction?mid=${mid}&orderId=${oid}`,
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': post_data.length,
},
};
var response = '';
var post_req = https.request(options, function (post_res) {
post_res.on('data', function (chunk) {
response += chunk;
});
post_res.on('end', function () {
resolve(response);
});
});
post_req.write(post_data);
post_req.end();
});
};
const reqdata = await requestAsync();
res.send(200).json(reqdata);
}
}

Axios POST request to Twillio returns with an Authentication Error?

in Node.js, I am trying to send a POST request with Axios to Twilio and send an SMS message to my phone. But I am getting an 'error: Authentication Error - No credentials provided ? Here is the code:
const body = {
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8',
Body: 'hi from vsc',
To: toNumber,
From: fromNumber,
};
const headers = {
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8',
Authorization: `Basic ${accountSID}:${authToken}`,
};
exports.axios = () => axios.post(`https://api.twilio.com/2010-04-01/Accounts/${accountSID}/Messages.json`, body, headers).then((res) => {
console.log(res, 'res');
}).catch((err) => {
console.log(err);
});
I also tried to use the same parameters with POSTMAN and the POST request is successful. I also tried to encode my authorization username and password to Base 64, but with no success.
I wrote to Twilio customer help but haven`t received any replies yet.
Axios makes an auth option available that takes an object with username and password options. You can use this with the username set to your account SID and password set to your auth token.
The headers object should be sent as the headers parameter of a config object in the third parameter to axios.post. Like so:
const params = new URLSearchParams();
params.append('Body','Hello from vcs');
params.append('To',toNumber);
params.append('From',fromNumber);
const headers = {
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8',
};
exports.axios = () => axios.post(
`https://api.twilio.com/2010-04-01/Accounts/${accountSID}/Messages.json`,
params,
{
headers,
auth: {
username: accountSID,
password: authToken
}
}
}).then((res) => {
console.log(res, 'res');
}).catch((err) => {
console.log(err);
});
Headers is actually a field of config, try something like this:
const config = {
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8',
Authorization: `Basic ${accountSID}:${authToken}`,
}
}
axios.post(URL, data, config).then(...)
Or this (general example calling a Twilio endpoint)
const axios = require('axios');
const roomSID = 'RM1...';
const participantSID = 'PA8...';
const ACCOUNT_SID = process.env.ACCOUNT_SID;
const AUTH_TOKEN = process.env.AUTH_TOKEN;
const URL = "https://insights.twilio.com/v1/Video/Rooms/"+roomSID+"/Participants/"+participantSID;
axios({
method: 'get',
url: URL,
auth: {
username: ACCOUNT_SID,
password: AUTH_TOKEN
}
})
.then((response) => {
console.log(response.data);
})
.catch((error) => {
console.log(error);
});
Working code:
const params = new URLSearchParams();
params.append('Body','Hello from vcs');
params.append('To',toNumber);
params.append('From',fromNumber);
exports.axios = () => axios.post(
`https://api.twilio.com/2010-04-01/Accounts/${accountSID}/Messages.json`,
params,
{
auth: {
username: accountSID,
password: authToken,
},
},
).then((res) => {
console.log(res, 'res');
}).catch((err) => {
console.log(err);
});
The previous solutions did not work for me. I encountered either the Can't find variable: btoa error or A 'To' phone number is required..
Using qs worked for me:
import qs from 'qs';
import axios from 'axios';
const TWILIO_ACCOUNT_SID = ""
const TWILIO_AUTH_TOKEN = ""
const FROM = ""
const TO = ""
const sendText = async (message: string) => {
try {
const result = await axios.post(
`https://api.twilio.com/2010-04-01/Accounts/${TWILIO_ACCOUNT_SID}/Messages.json`,
qs.stringify({
Body: message,
To: TO,
From: FROM,
}),
{
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
auth: {
username: TWILIO_ACCOUNT_SID,
password: TWILIO_AUTH_TOKEN,
},
},
);
console.log({result});
} catch (e) {
console.log({e});
console.log({e: e.response?.data});
}
};

How can I get Axios to send a request with FormData?

I'm unable to get the server that I'm calling to recognize the FormData that I'm providing when I use axios. It keeps telling me that I'm not providing the right FormData even though it works in Postman and Node native http (see below):
import { Router } from "express";
import axios from "axios";
import * as FormData from "form-data";
const router = Router();
const cookieHeader = {
Cookie: "XXX",
};
router.get("/", async (_req, res) => {
try {
const formData = new FormData();
formData.append("key1", JSON.stringify(["value1"]));
formData.append("key2", "value2");
formData.append("key3", "value3");
const response = await axios.post("https://xxx", formData, { headers: { "Content-Type": "multipart/form-data; boundary=--------------------------811161660471543283806813" } });
res.send(response.data);
} catch (error) {
console.log(error);
}
});
module.exports = router;
I am able to get it working in Postman and used that to export using Node's native http, which also works:
import { Router } from "express";
import { https } from "follow-redirects";
const router = Router();
router.get("/", () => {
const options = {
method: "POST",
hostname: "xxx",
path: "/xx/xxx",
headers: {
"Content-Type": "multipart/form-data; boundary=--------------------------811161660471543283806813",
Cookie: "xxx",
},
maxRedirects: 20,
};
const req = https.request(options, (res: any) => {
const chunks: any[] = [];
res.on("data", (chunk: any) => {
chunks.push(chunk);
});
res.on("end", () => {
const body = Buffer.concat(chunks);
console.log(body.toString());
});
res.on("error", (error: any) => {
console.error(error);
});
});
const postData = `------WebKitFormBoundary7MA4YWxkTrZu0gW\nContent-Disposition: form-data; name=\"key1\"\n\n[\"value1\"]\n------WebKitFormBoundary7MA4YWxkTrZu0gW\nContent-Disposition: form-data; name=\"key2\"\n\nvalue2\n------WebKitFormBoundary7MA4YWxkTrZu0gW\nContent-Disposition: form-data; name=\"key3\"\n\nvalue3\n------WebKitFormBoundary7MA4YWxkTrZu0gW--`;
req.setHeader("content-type", "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW");
req.write(postData);
req.end();
});
module.exports = router;
I figured it out after reading through https://github.com/axios/axios/issues/318. It wasn't until near the end that Googrosh posted that he used .getHeaders(). Lo and behold, I added that to my headers too and it worked.
So updating my code, here's what it looks like:
const response = await axios.post("https://xxx", formData, { headers: formData.getHeaders() });
onst formUrlEncoded = x =>
Object.keys(x).reduce((p, c) => p + `&${c}=${encodeURIComponent(x[c])}`, '')
var axios = require("axios");
axios({
url: 'https://login.xyz.com/oauth/v2/token',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
data: formUrlEncoded({
client_id: '***',
client_secret: '***',
grant_type: 'authorization_code',
})
})
.then(function(response) {
console.log(response.data)
})
.catch(function(error) {
console.log(error)
})

Resources