2

This might seem really silly but I'm trying to get some data from an API (WHMCS). In the docs they have code something like this:

// Call the API 
$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL, $whmcsUrl . 'includes/api.php'); 
curl_setopt($ch, CURLOPT_POST, 1); 
curl_setopt($ch, CURLOPT_TIMEOUT, 30); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1); 
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); 
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postfields)); 
$response = curl_exec($ch); 
if (curl_error($ch)) { 
die('Unable to connect: ' . curl_errno($ch) . ' - ' . curl_error($ch)); 
} 
curl_close($ch); 
 
// Decode response 
$jsonData = json_decode($response, true); 
 
// Dump array structure for inspection 
var_dump($jsonData); 

I've written code in nodejs using axios which aims to do the same thing:

axios.get(whmcsUrl + `includes/api.php?accesskey=${apiAccessKey}`, postFields)
.then(res => console.log(res))
.catch(err => console.log(err))

Don't have a deep knowledge of either PHP or Node, please help! I'm getting a 403 Forbidden when I execute this request in node? What am I doing wrong.

Update: Instead of passing an object (postFields), I'm now passing things like username or pw in the url itself:

axios.post(whmcsUrl + `includes/api.php?action=${apiAction}&username=${apiIdentifier}&password=${apiSecret}&accesskey=${apiAccessKey}&responsetype=json`)
.then(res => console.log(res))
.catch(err => console.log(err))

Its still giving me 403 Forbidden error.

Amol Borkar
  • 2,321
  • 7
  • 32
  • 63

1 Answers1

3

The axios equivalent of CURLOPT_POSTFIELDS, http_build_query($postfields) is twofold - first stringify the params and pass them as the post body and secondly specify application/x-www-form-urlencoded as the content type in the headers.

Something like this:

const axios = require('axios')
const qs = require('qs')

const data = qs.stringify(postFieldsObject)
const config = {
  method: 'post',
  url: `${whmcsUrl}includes/api.php`,
  headers: { 
    'Content-Type': 'application/x-www-form-urlencoded'
  },
  data : data
}

axios(config)
.then(function (response) {
  console.log(JSON.stringify(response.data))
})
.catch(function (error) {
  console.log(error)
})
cyberwombat
  • 38,105
  • 35
  • 175
  • 251
  • Thanks! Can this be done without `qs` package? I'm not using node anymore. – Amol Borkar Aug 26 '20 at 09:57
  • 1
    Yes 'qs.stringify'.You can also build it by hand easily. The key points are that this string is the POST data and not part of the URL and secondly the proper content type header must be passed. – cyberwombat Aug 27 '20 at 15:42