Encoding password field for HTTP Basic Auth - php

I using PHP cURL to communicate with a Rest API. Most of the functionality is carried out using X-Ephemeral-Tokens, but unfortunately they don't allow delete permissions to be given through these, so I am having to implement a function to delete through HTTP Basic Authentication.
The trouble I'm having is that the password for the testing account is a random string, including multiple special characters (double quotation marks being some of them). I got the request working using the normal cURL binary by surrounding the username:password combination in single quotes (i.e. ') but I'm not sure how to convert this to PHP. The relevant snippet is below.
$curl = curl_init();
curl_setopt($curl, CURLOPT_HTTPHEADER, array("Accept: application/json",
"Content-Type: application/json"));
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl, CURLOPT_USERPWD, $uname . ":" . $pass);
curl_setopt($curl, CURLOPT_URL, "https://cloud.ravellosystems.com/api/v1/applications/" . $appid);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "DELETE");
$result = curl_exec($curl);
I've tried various combinations of quotation marks and URL encoding but I still get a response code which indicates the authentication isn't working right.
This is and exmaple HTTP request based on what the API documentation shows for using normal cURL (amended slightly)
curl -v -X DELETE -H "Content-Type: application/json" -H "Accept: application/json" --user ravello#ravello.com:password https://cloud.ravellosystems.com/api/v1/applications/414244
Any suggestions on how to get around this greatly appreciated.

Ok so if anyone else has this issue, I've found a solution.
Basically you can see in my code above that I was trying to use the cURL PHP methods to set options for CURLOPT_USERPWD and CURLOPT_HTTPAUTH. However somewhere in this the special characters in the password were causing issues with the parsing and I think only a section of it was actually being taken by the server.
However, all that these options do basically is set an HTTP header, as can be seen in #mpyw screenshots. This is the Authorization header, which is in the format below:
`Authorization: Basic [base64 encoded username:password]`
So I got rid of these options and did it manually, by base64 encoding my username:password string myself and then adding a header.
$auth = base64_encode($uname . ":" . $pass);
curl_setopt($curl, CURLOPT_HTTPHEADER, array("Authorization: Basic $auth",
"Accept: application/json",
"Content-Type: application/json"));
Now it all works fine! Thanks to the guys who posted answers - both of you contributed to me coming up with the workaround.

I compared two ways, enabling verbose outputs.
Emitted headers are the same, except that the PHP does not contain User-Agent header. Does the API require User-Agent header?
Edit
Password that contains '
Password that contains "

I believe that you have to base64_encode the username and password. Try this:
curl_setopt($curl, CURLOPT_USERPWD, base64_encode($uname . ":" . $pass));

Related

PHP CURL issue with an API when retrieving datas

we have an API existing with a distributor.
Our software is running under PHP 7.3.6 / Apache 2.4.38
We already successfully did some other actions: creating new purchase orders, retrieving orders, ...
We have a problem to retrieve invoices.
We are using for our API tests a software called POSTMAN.
We input all the informations (api key, ....)
Using POSTMAN, it works perfectly. There is an option in POSTMAN to obtain the code in different langage. For our needs, we took the PHP generated code. The problem is that it is not working.
We also used https://reqbin.com/curl and it works perfectly. But same problem, the generated code in PHP is not working.
For example, in postman or reqbin, this CURL code is working
curl -X GET https://url.com/Invoices?startDate="01-01-2019"&endDate="01-31-2023" \
-H 'Accept: application/json' \
-H 'Authorization: Bearer generatedtokenzzzzzzzzzzzzzzzzzzzzzzzzzzz' \
-H 'Content-Type: application/json' \
-H 'zzzzzzzzz-API-Key: generatedapikeyzzzzzzzzzzzzzz'
when we click on generate PHP code we have this code:
<?php
$url = "https://url.com/Invoices?startDate="01-01-2019"&endDate="01-31-2023";
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$headers = array(
"Accept: application/json",
"Authorization: Bearer generatedtokenzzzzzzzzzzzzzzzzzzzzzzzzzzz",
"Content-Type: application/json",
"zzzzzzzzz-API-Key: generatedapikeyzzzzzzzzzzzzzz",
);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
//for debug only!
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
$resp = curl_exec($curl);
curl_close($curl);
var_dump($resp);
?>
Because it didn't work , we tried to add some options like
CURLOPT_CUSTOMREQUEST => 'GET',
and it still don't work.
We are getting crazy, we are on this problem for more than a week....
Any help would be very usefull.
Many thanks by advance....
We find the bug.
it was not in the part of this code but it was above.
a parameter was not passed correctly, and the error message {message": "list index out of range} was in fact wrong.

How do I make this Salesforce cURL request in PHP?

I'm using PHP to make cURL requests to Salesforce's REST API.
I've got most of the requests I need to make figured out, but I'm not sure how to convert the following curl command on the following Salesforce API page to a cURL request in PHP:
curl https://yourInstance.salesforce.com/services/data/v20.0/sobjects/Account/customExtIdField__c/11999 -H "Authorization: Bearer token" -H "Content-Type: application/json" -d #newrecord.json -X PATCH
https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/dome_upsert.htm
I know that that -H option is for headers, which I'm handing with the following:
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
And I think that the -X PATCH part can be accomplished with the following PHP cURL option:
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH');
However, how do I handle the -d #newrecord.json part in PHP cURL?
Thanks.
You should POST the json
$post = json_encode($data);
curl_setopt($ch, CURLOPT_POSTFIELDS,$post);
What you are doing with -d #newrecord.json is uploading a (JSON) file for the endpoint to use. To replicate this in PHP, you need to pass an array with a file element to CUROPT_POSTFIELDS, like this:
$file = [
"file" => "#newrecord.json";
];
curl_setopt($ch, CURLOPT_POSTFIELDS, $file);
Make sure to give the correct file path. You can use realpath() to aid with this.
Alternatively, you could just send the JSON encoded data:
$data = [
"site" => "Stack Overflow",
"help" => true,
];
$jsonData = json_encode($data);
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);
Don't forget to set your Content-Type: application/json header!
Lastly, your guess about the PATCH request is correct:
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH');

Using PHP to create Confluence Wiki pages

I've been able to use PHP in order to generate JIRA issues, but was wondering if it is possible to also create Confluence wiki pages that link back to the JIRA issue. I haven't been able to make this work yet. Does anyone have any examples on how this is accomplished?
With this code in php, you can create Confluence Pages:
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://localhost:8090/rest/api/content/");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "{\"type\":\"page\",\"title\":\"inserttitle\",\"space\":{\"key\":\"insertspace\"},\"ancestors\":[{\"type\":\"page\",\"id\":insertancestor}],\"body\":{\"storage\":{\"value\":\"<p>This is a new page</p>\",\"representation\":\"storage\"}}}");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, "insertusername" . ":" . "insertpassword");
$headers = array();
$headers[] = "Content-Type: application/json";
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
curl_close ($ch);
?>
You can easily create a new Confluence page using the REST API. Here's an example using curl:
curl -u admin:admin -X POST -H 'Content-Type: application/json' -d'{"type":"page","title":"new page","space":{"key":"TST"},"body":{"storage":{"value":"<p>This is a new page</p>","representation":"storage"}}}' http://localhost:8080/confluence/rest/api/content/
The next thing to do would be for PHP to call that. Check the following for examples:
PHP curl post
Basic authentication in PHP curl
Having done that, you could also embed a JIRA macro in the Confluence page for extra zing. That would mean that the original curl would add the JIRA macro as the storage format (in a Confluence page, click on Tools (or "..." now) and select View Storage Format for an example.
Here's an example of the JIRA macro:
<ac:structured-macro ac:name="jira">
<ac:parameter ac:name="server">Example JIRA</ac:parameter>
<ac:parameter ac:name="serverId">fdsafds-68es-3615-a6f7-71427b983092</ac:parameter>
<ac:parameter ac:name="key">XYZ057-172</ac:parameter>
</ac:structured-macro>
You'll need to figure out your server name, serverId & JIRA issue key yourself.
This would mean the original curl looks like this:
curl -u admin:admin -X POST -H 'Content-Type: application/json' -d'{"type":"page","title":"new page","space":{"key":"TST"},"body":{"storage":{"value":"<p>This is a new page with a JIRA macro added:</p><ac:structured-macro ac:name="jira"><ac:parameter ac:name="server">Example JIRA</ac:parameter><ac:parameter ac:name="serverId">fdsafds-68es-3615-a6f7-71427b983092</ac:parameter><ac:parameter ac:name="key">XYZ057-172</ac:parameter></ac:structured-macro>","representation":"storage"}}}' http://localhost:8080/confluence/rest/api/content/

Authorization header is not set with PHP cURL

I'm trying to make an API-call from PHP using cURL.
This is my code:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://localhost/api/");
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(array('sql' => $sql)));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: MY-API-KEY'));
$response = curl_exec($ch);
curl_close($ch);
It seems as if the Authorization-header is not set. I've tried to Google around, where some say that the header is not recognized correctly. Can anyone help?
My code does work for API-calls without Authorization needed.
UPDATE:
Calling the command via the command line tool curl:
curl -H 'Authorization: MY-API-KEY'...
everything works.
My feedback from the PHP cURL is "Access denied".
Because it does't look its constructed properly:
Client side:
When the user agent wants to send the server authentication credentials it may use the Authorization header.
The Authorization header is constructed as follows:
Username and password are combined into a string "username:password"
The resulting string is then encoded using the RFC2045-MIME variant of Base64, except not limited to 76 char/line
The authorization method and a space i.e. "Basic " is then put before the encoded string.
For example, if the user agent uses 'Aladdin' as the username and 'open sesame' as the password then the header is formed as follows:
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

Using PHP to post an XML buffer to an HTTPS page

I am using php 5.2.9
I have an XML buffer which I need to post to some HTTPS URL.
What is the correct way of doing that?
I see various examples on the web, and none of them seem to be working for me:
Some define the cURL headers like so:
$headers = array(
"POST " . $page . " HTTP/1.0",
"Content-type: text/xml;charset=\"utf-8\"",
"Accept: text/xml",
"Cache-Control: no-cache",
"Pragma: no-cache",
"SOAPAction: \"run\"",
"Content-length: ".strlen($buffer),
);
Where $page holds the request on the server and $buffer contains the XML data.
The actual $buffer is sent as the value as:
curl_setopt($curl, CURLOPT_POSTFIELDS, $buffer);
But I don't see how this can work, as CURLOPT_POSTFIELDS expects its value to be an array and not a buffer.
Then I saw several ways of configuring the SSL aspects of the call:
curl_setopt($curl, CURLOPT_SSLVERSION,3);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);
Are all of these needed? I saw examples where the following was also set:
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC );
curl_setopt($curl, CURLOPT_USERPWD, "username:password");
Can someone post a complete working example that explains what needs to be done in order to post an XML buffer using cURL to an HTTP URL?
Thanks in advance
A few points:
Don't specify the request method with the other headers. Use CURLOPT_CUSTOMREQUEST for that.
To send the data you have two options. You can either implement a stream wrapper that reads from $buffer that you then open with fopen and give as a CURLOPT_INFILE option (of course, if the XML is on disk, you can open it directly with fopen), or, more simply, you define a CURLOPT_READFUNCTION callback.
The verify peer part is only necessary if you want to check the validity of the server's certificate (you ought to).
Basic authentication is necessary if the server requires basic authentication. Only you can know that.

Categories