0

I'm working with this not-so-great ASAP Connected documentation. It's written for .NET, but I'm creating a WordPress plugin in PHP with it for a client.

To get authorisation, it's providing this snippet:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://stagingapi.asapconnected.com/api/login");
request.Headers.Add(HttpRequestHeader.Authorization, "user=username&organizationId=id&password=password&apiKey=apikey");
request.Accept = "application/json";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
string accessToken = response.Headers["asap_accesstoken"];

In my plugin, I'm attempting to do this with this:

$request_url = 'https://stagingapi.asapconnected.com/api/login';
$headers = array(
    //Accept or Content type
    'Accept: application/json',
    //Authorisation
    'Authorization: ' . http_build_query(array(
        'user' => ASAPCONNECTED_USERNAME,
        'password' => ASAPCONNECTED_PASSWORD,
        'organizationId' => ASAPCONNECTED_ORGANIZATION_ID,
        'apiKey' => ASAPCONNECTED_API_KEY
)));
$curl = curl_init($request_url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); //Return response as string instead of display
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); //Ignore any SSL errors
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); //Specify our header
curl_setopt($curl, CURLOPT_HTTPGET, true); //Specify that this is a GET request
$response = curl_exec($curl); //Execute cURL and collect the response
$curl_info = curl_getinfo($curl); //Retrieve it's info
$curl_error = curl_error($curl); //Retrieve it's error
curl_close($curl); //Close the cURL
if ($curl_error || !$response) {
    if ($curl_error) {
        //An error occurred requesting authorisation from the API!
    }
    if (!$response) {
        //The response was empty when requesting authorisation from the API!
    }
} else {
    //The API authorisation request was a success! Do stuff...
}

So I thought that the "GetResponse" is like a GET request, and the documentation and it's snippet very clearly put the API credentials in an "Authorization" header. However, the response I get is empty! It doesn't return any errors. When I log the $curl_info variable, it outputs this (some data omitted):

[01-Jul-2020 21:03:36 UTC] Array
(
    [url] => https://stagingapi.asapconnected.com/api/login
    [content_type] => 
    [http_code] => 401
    [header_size] => 765
    [request_size] => 222
    [filetime] => -1
    [ssl_verify_result] => 0
    [redirect_count] => 0
    [total_time] => 0.183425
    [namelookup_time] => 0.00508
    [connect_time] => 0.006237
    [pretransfer_time] => 0.047479
    [size_upload] => 0
    [size_download] => 0
    [speed_download] => 0
    [speed_upload] => 0
    [download_content_length] => 0
    [upload_content_length] => -1
    [starttransfer_time] => 0.183389
    [redirect_time] => 0
    [redirect_url] => 
    [certinfo] => Array
        (
        )

    [http_version] => 2
    [protocol] => 2
    [ssl_verifyresult] => 0
    [scheme] => HTTPS
    [appconnect_time_us] => 47412
    [connect_time_us] => 6237
    [namelookup_time_us] => 5080
    [pretransfer_time_us] => 47479
    [redirect_time_us] => 0
    [starttransfer_time_us] => 183389
    [total_time_us] => 183425
)

Any ideas?

AuRise
  • 2,253
  • 19
  • 33
  • 1
    The access token is in the response header, not the data. You need to use `CURLOPT_HEADER` to include this in the response, and then you have to parse the returned headers. I don't think `curl` provides any automatic header parsing. – Barmar Jul 01 '20 at 21:17
  • See https://stackoverflow.com/questions/34670134/http-parse-headers-with-pecl-http/34792452#34792452 – Barmar Jul 01 '20 at 21:20
  • Aha! Well that got me a step closer @Barmar! Thank you! So after adding `curl_setopt($curl, CURLOPT_HEADER, true);` it's hitting the success function. Though within the response, it's now telling me `asap_accesstoken: There's no authorization parameters`. Did I not send the credentials in headers correctly? – AuRise Jul 01 '20 at 21:24
  • It looks like it should be right – Barmar Jul 01 '20 at 21:29
  • Alright, well thank you @Barmar for getting me this far. I guess I'll reach out to their support team for the credentials again. The sentence in their documentation `Note: the username and password is unique to your integration application, and is not related to your regular ASAP application credentials.` makes me believe that my client provided me their login credentials, and not integration app credentials, and that perhaps those two are _not_ the same. – AuRise Jul 01 '20 at 21:32
  • Although if it worked with .NET the same credentials should work for you. – Barmar Jul 01 '20 at 21:33
  • @Barmar I didn't write this script in .NET to know if the credentials work, and their _wonderful_ sandbox feature (https://stagingapi.asapconnected.com/swagger/ui/index#!/Courses/Courses_GetCourses) always returns the `Access Token has been expired` error (it doesn't use our credentials or API key anyway, so whatever configuration that is, it's not on me to fix it), so I've yet to see a working version of this code in either language. – AuRise Jul 02 '20 at 00:08
  • @Barmar To sum it up, the ASAP Connected support team gave me incorrect credentials the first time *face palm* I got the correct ones now and it's working perfectly. Thank you for your help! If you want to post your comment about the `CURLOPT_HEADER` into an answer, I'll mark it as solved. Thanks! – AuRise Jul 15 '20 at 18:52
  • I don't have the time right now to write an answer. You can post your code as an answer. – Barmar Jul 15 '20 at 20:01

1 Answers1

0

@Barmar pointed out that in the documentation for the ASAP Connected API, the access token is in the headers of the response. I only needed to add curl_setopt($curl, CURLOPT_HEADER, true); to include those headers in the response, so my request in PHP looks like this:

$request_url = 'https://stagingapi.asapconnected.com/api/login';
$headers = array(
    //Accept or Content type
    'Accept: application/json',
    //Authorisation
    'Authorization: ' . http_build_query(array(
        'user' => ASAPCONNECTED_USERNAME,
        'password' => ASAPCONNECTED_PASSWORD,
        'organizationId' => ASAPCONNECTED_ORGANIZATION_ID,
        'apiKey' => ASAPCONNECTED_API_KEY
)));
$curl = curl_init($request_url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); //Return response as string instead of display
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); //Ignore any SSL errors
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); //Specify our header
curl_setopt($curl, CURLOPT_HEADER, true);//Include headers in response
curl_setopt($curl, CURLOPT_HTTPGET, true); //Specify that this is a GET request
$response = curl_exec($curl); //Execute cURL and collect the response
$curl_info = curl_getinfo($curl); //Retrieve it's info
$curl_error = curl_error($curl); //Retrieve it's error
curl_close($curl); //Close the cURL
if ($curl_error || !$response) {
    if ($curl_error) {
        //An error occurred requesting authorisation from the API!
    }
    if (!$response) {
        //The response was empty when requesting authorisation from the API!
    }
} else {
    //The API authorisation request was a success! Do stuff...
}

Thanks again, @Barmar !!

Just a word of caution: their support team doesn't seem incredibly knowledgeable about their own product. So when asking for API credentials, be very specific. The first time I asked, they gave me a temporary access token that expires in over a year. The second time I asked, they gave me incorrect credentials. The third time was a charm. Unfortunately, you have to open a ticket with them to get these credentials as they are not available in the admin dashboard anywhere.

If anyone else is working with this API using PHP and has any questions, I'd be happy to help since I'm also on this journey. I might even write up a tutorial or two when this project is over.

AuRise
  • 2,253
  • 19
  • 33