I'm working on a PHP script that has to connect to an REST API. The provider of the API, suggested to use cURL. They gave me an example of how to use it in the command line:
curl -D- -u "user:password" -X GET -H "Content-Type: application/json" http://example.com/api/searchFunction?jql=assignee=user1
The PHP script is the following:
<?php
$defaults = array(
CURLOPT_HEADER => true,
CURLOPT_URL => 'http://example.com/api/searchFunction?jql=assignee=user1',
CURLOPT_USERPWD => "user:password",
CURLOPT_HTTPAUTH => 'CURLAUTH_BASIC'
);
$ch = curl_init();
curl_setopt_array($ch, ($defaults));
echo "cURL output: ".curl_exec($ch);
curl_close($ch);
?>
As you can imagine, the command line version works fine, but in the PHP version I got the following error:
Field 'assignee' does not exist or this field cannot be viewed by anonymous users.
That suggests that the user login validation doesn't works. However, the user and password are correct.
I was looking for already answered posts of cURL parameters equivalents between the command line version and the PHP version but couldn't find the correct parameters for the PHP version.
You haven't fully replicated your cURL command yet.
For starters, you've never set the Content-Type: application/json header option. You need to set that using the CURLOPT_HTTPHEADER option.
Secondly, command line cURL and PHP's cURL use different User-Agent values.
Consider enabling the command line cURL's verbose option so you can see all the information it's sending, then replicate it PHP.
Related
What is correct interpretation of curl payment method prepared on [stripe][1]
curl https://api.stripe.com/v1/payment_methods \
-u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \
-d type=card \
-d "card[number]"=4242424242424242 \
-d "card[exp_month]"=10 \
-d "card[exp_year]"=2022 \
-d "card[cvc]"=314
my code is:
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://api.stripe.com/v1/payment_methods',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => 'type=card&card%5Bnumber%5D=4242424242424242&card%5Bexp_month%5D=10&card%5Bexp_year%5D=2022&card%5Bcvc%5D=314',
CURLOPT_HTTPHEADER => array(
'Authorization: Basic c2tfdGVzdF80ZUMzOUhxTHlqV0Rhcmp0VDF6ZHA3ZGM6',
'Content-Type: application/x-www-form-urlencoded'
),
));
$response = curl_exec($curl);
curl_close($curl);
But I dont know how to use: -u sk_test_4eC39HqLyjWDarjtT1zdp7dc: \ in curl_setopt_array
on cURL or bash "-u" designed user or password (u of user)
on cURL php it is :
CURLOPT_USERPWD
curl_setopt($ch, CURLOPT_USERPWD, "sk_test_4eC39HqLyjWDarjtT1zdp7dc");
For more info with stripe curl CURLOPT_USERPWD, check the link : Stripe API - PHP Curl request behind a proxy
Taken from https://curl.se/docs/manpage.html#-u:
-u, --user <user:password>
Specify the user name and password to use for server authentication. Overrides -n, --netrc and
--netrc-optional.
If you simply specify the user name, curl will prompt for a password.
The user name and passwords are split up on the first colon, which
makes it impossible to use a colon in the user name with this option.
The password can, still.
On systems where it works, curl will hide the given option argument
from process listings. This is not enough to protect credentials from
possibly getting seen by other users on the same system as they will
still be visible for a brief moment before cleared. Such sensitive
data should be retrieved from a file instead or similar and never used
in clear text in a command line.
When using Kerberos V5 with a Windows based server you should include
the Windows domain name in the user name, in order for the server to
successfully obtain a Kerberos Ticket. If you don't then the initial
authentication handshake may fail.
When using NTLM, the user name can be specified simply as the user
name, without the domain, if there is a single domain and forest in
your setup for example.
To specify the domain name use either Down-Level Logon Name or UPN
(User Principal Name) formats. For example, EXAMPLE\user and
user#example.com respectively.
If you use a Windows SSPI-enabled curl binary and perform Kerberos V5,
Negotiate, NTLM or Digest authentication then you can tell curl to
select the user name and password from your environment by specifying
a single colon with this option: "-u :".
If this option is used several times, the last one will be used.
Example:
curl -u user:secret https://example.com
In short, it is for basic HTTP authentication.
I have a situation while trying to do a GET method with curl to get xml from distant web api.
$url = 'xxxx.com'
$key = '/KEY/PRIVATE.KEY'
$perm = '/KEY/CERT.PEM'
$options = array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSLCERT => $perm ,
CURLOPT_SSLKEY => $key,
CURLOPT_HEADER => false,
);
$curl = curl_init();
curl_setopt_array($curl , $options);
$resp = curl_exec($curl);
curl_close($curl);
I have to link SSL cert and pem, but $resp is always returned as false.
This is what my cURL request should be in command prompt :
curl -k -v -X GET "[-URL-]" --cert ./KEY/CERT.pem --key ./KEY/PRIVATE.KEY
Any help would be strongly appreciated...
EDIT
So, I used two methods to try to debug :
With stderr I have:
string ''.' unknown as intern or extern command, program file or executable file
' (length=117)
And with die(curl_error($curl)) I get this :
unable to use client certificate (no key found or wrong pass phrase?)
So, I actually make my URL with two string ($url = a . b), but this is supposed to work, or am I crazy?
For the ssl error, I don't get why I have this issue since this works totally fine on command prompt...
EDIT 2
So, I found out how to solve in part my issue : I had to use realpath().
But now I have a new issue :
SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
So, I found some responses on stackoverflow that say to update cacert.pem file.
I did it, added CURLOPT_CAINFO => $cainfo,
in $options and put curl.cainfo = "PATH_TO/cacert.pem" in both of my php.ini (apache + php => WAMP). (PATH_TO already replaced by my true path).
Anyway, after all thoses changes, I still have the same issue.
I have to work under php 5.3, would it be the cause?
EDIT 3
Finnally found my answer. I should have look for curl options more carefully...
In command prompt -k allows an insecure connexion.
So, in php, I just have to set CURLOPT_VERIFYPEER to false.
FYI, I based myself on the doc that the distant web api gave to me .
Regards,
I had a lot of trouble figuring out why my php Curl API worked fine on a Mac using MAMP, but would not work under windows.
I asked fot debugging tips or useful information for finding curl configuration issues under windows.
The accepted answer contains a list of the steps that helped me get curl working on windows 7 32 bits.
If Curl still doesn't work, you can use file_get_contents to make POST requests. It works on all hostingers, all OS and on local.
$url = 'WhateverUrlYouWant';
$postdata = http_build_query(
array(
'id' => '202',
'form' => 'animal',
.....
)
);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $postdata
)
);
$context = stream_context_create($opts);
$result = file_get_contents($url,false, $context);
echo $result
Here is a list of steps for debugging Curl:
Check in phpinfo module that Curl IS enabled.
Verify extensions dir path is propperly set in php.ini and that extension=php_curl.dll is uncommented.
Check that Environment Variables are propperly set as per: http://php.net/manual/en/faq.installation.php#faq.installation.addtopath
Run deplister.exe ext\php_curl.dll to verify all dependencies are correctly satisfied.
If all of the above is working then check the output of CURLOPT_VERBOSE. As per #hp95 suggestion in the following thread: No Response getting from Curl Request to https server
If you are reaching a site that uses SSL check the following post: HTTPS and SSL3_GET_SERVER_CERTIFICATE:certificate verify failed, CA is OK
And fix it like these:
https://snippets.webaware.com.au/howto/stop-turning-off-curlopt_ssl_verifypeer-and-fix-your-php-config/
reverse
curl_close($curl);
print_r($response);
** this is a broken protocol **
to
print_r($response);
curl_close($curl);
** print your results BEFORE closing, which destroys (empties) the $response **
I'm trying to send an Ajax request using cURL PHP but it gives the error
Unknown SSL protocol error in connection
while I'm able to login to same server.
I've tried this
curl_setopt( $ch, CURLOPT_SSLVERSION, 1 );
and Ajax request is something like that
$header = array('Accept' => '*/*',
"X-Requested-With" => "XMLHttpRequest",
"Content-Type" => "application/x-www-form-urlencoded");
$data = array('ClientNumber=999999&OrderClass=ContractOrders&ShowAll=ContractOrders&ShowPerPage=500');
echo $page = Spider::spider($header, 'https://wfs.nursefinders.com/MasterConsole/displayorders.cfm?ShowAll=ContractOrders', 'https://wfs.nursefinders.com/MasterConsole/BuildOrderDisplaySection.cfm', FALSE, $data[0]);
Note in spider function, first argument is header, second is referrer third is url to access, fourth doesn't matter it's for cookie file and fifth is data o post
I'm using UBUNTU 14.10 and cURL Version is curl 7.37.1 according to this command /usr/bin/curl -V
and same as printing by php phpinfo()
Please help
I believe the reason for your problem is that the server you are communicating with does not support your SSL protocol.
There is a page here with information on that: http://blog.techstacks.com/2010/03/3-common-causes-of-unknown-ssl-protocol-errors-with-curl.html
For more direct information, try looking into the API Documentation for the required connection protocol for their server. They may have provided a sample that will connect.
This server is terrible broken. It does not support the most compatible SSLv23 handshake and will just hang if one tries it. It only supports explicit SSL 3.0 or TLS 1.0 handshakes. From looking at the source code of cURL it seems to me, that all variations of enforcing TLS1.0+ will do a SSLv23 handshake, which the server can not do:
-- curl-7.41.0/lib/vtls/openssl.c
1719 default:
1720 case CURL_SSLVERSION_DEFAULT:
1721 case CURL_SSLVERSION_TLSv1:
1722 case CURL_SSLVERSION_TLSv1_0:
1723 case CURL_SSLVERSION_TLSv1_1:
1724 case CURL_SSLVERSION_TLSv1_2:
1725 /* it will be handled later with the context options */
1726 req_method = SSLv23_client_method();
This leaves only the option of using the insecure SSL 3.0, that is
curl_setopt( $ch, CURLOPT_SSLVERSION, 3 );
While I have no PHP to test with, a short test with curl -1 vs. curl -3 on the command line confirms that CURLOPT_SSLVERSION of 1 will not work while 3 should work.
I am trying to send a REST request. The example I have been given by the system docs is this:
$ curl --digest -u admin:<passwd> http://1.2.3.4/r/users/12345/calls/recent
{"data": [
{"state_msg": "Finished",
"code": 200,
"dst_codecs": "PCMU,PCMA,iLBC,telephone-event",
"src_codecs": "PCMU,PCMA,telephone-event,iLBC",
"pid": 1250018007,
"url": "\/r\/users\/12345\/calls\/1250018007:16739",
[...]
}
[...]
]}
what is this example trying to tell me? what is the data information there? Is that what i need to send. If so, how would i send it? I have read this post: Call a REST API in PHP but I am still unsure of how to structure my call. would it be something like this?
$data = array('state_msg' => 'state_msg','code'=>'200'.....);
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl, CURLOPT_USERPWD, "admin:<password>");
curl_setopt($curl, CURLOPT_URL, "http://1.2.3.4/r/users/12345/calls/recent");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
I start with the beginning of the example:
$ curl
The $ sign denotes a unix shell prompt with standard user privileges.
Then a space separates the command which is curl here.
Each command has (normally) a manual page, you get it with the man command:
$ man curl
That should explain all the rest to you, as those man-pages explain all of the commands switches and options.
If you don't have such a shell prompt at hand and you do not like to consider installing one, many commands have their man pages as well in the internet. Here for curl:
http://curl.haxx.se/docs/manpage.html
After you've understood what that concrete command does, you just look-up the related options in the PHP manual on the curl_setopt page. How this works is demonstrated in the following example:
Convert command line cURL to PHP cURL
Example:
$ curl --digest -u admin:<passwd> http://1.2.3.4/r/users/12345/calls/recent
########
This switch relates to the CURLAUTH_DIGEST value of the CURLOPT_HTTPAUTH setting.
$handle = curl_init($url);
curl_setopt_array($handle, [
...
CURLOPT_HTTPAUTH => CURLAUTH_DIGEST, // --digest
...
]);
Compare with the Curl C-API which is just wrapped by PHP:
How to post http request using digest authentication with libcurl