I'm having troubles trying to get an access token from an oauth endpoint.
I'm making a curl POST request in the following way
$username = 'Joe';
$password = 'Doe##!'
$auth = 'Basic Y245Y3BleGF4aTp2ZWludGZxMmVwbGd5anU1Y2N6aGZtNmZ3OXdlNmJ=';
$headers = [
'Authorization' => $auth,
'Content-Type' => 'application/x-www-form-urlencoded',
];
$form_params = [
'username' => $username,
'password' => $password,
'grant_type' => 'password',
'scope' => 'auto'
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://oauth.wildapricot.org/auth/token");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($form_params));
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
return $response;
but I keep getting a invalid client error (the $auth variable consists in the client and secret encoded with base 64).
I've tried encoding the postfields but didn't help. I've hardcoded the $auth variable just in case the base64_encode function was messing it up (I generated it with that function before), but it didn't change anything.
I've checked that the endpoint was actually working with Postman and it actually is.
Any ideas on what could be the issue?
Edit: I've just added some debugging lines into the code and this is what I got (if that's of any help)
* Trying 34.226.77.200:443...
* TCP_NODELAY set
* Connected to oauth.wildapricot.org (34.226.77.200) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:#STRENGTH
* successfully set certificate verify locations:
* CAfile: /usr/local/etc/openssl/cert.pem
CApath: /usr/local/etc/openssl/certs
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server did not agree to a protocol
* Server certificate:
* subject: C=CA; postalCode=M5J 2L7; ST=Ontario; L=Toronto; street=144 Front Street West; O=Wild Apricot Inc.; OU=PremiumSSL Wildcard; CN=*.wildapricot.org
* start date: Sep 20 00:00:00 2018 GMT
* expire date: Nov 17 23:59:59 2020 GMT
* subjectAltName: host "oauth.wildapricot.org" matched cert's "*.wildapricot.org"
* issuer: C=GB; ST=Greater Manchester; L=Salford; O=COMODO CA Limited; CN=COMODO RSA Organization Validation Secure Server CA
* SSL certificate verify ok.
> POST /auth/token HTTP/1.1
Host: oauth.wildapricot.org
Accept: */*
Content-Length: 76
Content-Type: application/x-www-form-urlencoded
* upload completely sent off: 76 out of 76 bytes
* Mark bundle as not supporting multiuse
< HTTP/1.1 401 Unauthorized
< Cache-Control: no-cache
< Pragma: no-cache
< Content-Length: 68
< Content-Type: application/json; charset=utf-8
< Expires: -1
< WWW-Authenticate: Basic realm="authentication required"
< X-Powered-By: ASP.NET
< Access-Control-Allow-Origin: *
< Date: Fri, 15 Nov 2019 12:29:30 GMT
< Connection: close
< X-Backend-Server: lap1wue1b-62e2
< X-LB-Server: llblue1b-5471
<
* Closing connection 0
This line tells us there's a problem with your authentication:
WWW-Authenticate: Basic realm="authentication required"
Curl provides a simpler method for HTTP Basic auth. Try removing the Authorization header and setting the CURLOPT_USERPWD option instead:
curl_setopt($ch, CURLOPT_USERPWD, $username . ":" . $password);
Related
I'm trying to make a request to payment processing page. This requires authorization, which takes place through a set of redirects. In the second step, I get "411 Length Required" error, which means that content-length was lost along the way. Indeed, I cannot see it in the log. What can be done here? Change tool (programming language)?
CURLOPT_VERBOSE:
* Trying xxx.xxx.xxx.xxx...
* TCP_NODELAY set
* Connected to api.dev.example.com (188.186.236.44) port 443 (#0)
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
* subject: OU=Domain Control Validated; OU=PositiveSSL Wildcard; CN=*.dev.example.com
* start date: Apr 27 00:00:00 2019 GMT
* expire date: Apr 26 23:59:59 2021 GMT
* subjectAltName: host "api.dev.example.com" matched cert's "*.dev.example.com"
* issuer: C=GB; ST=Greater Manchester; L=Salford; O=Sectigo Limited; CN=Sectigo RSA Domain Validation Secure Server CA
* SSL certificate verify ok.
> POST /p2p/v2/payer HTTP/1.1
Host: api.dev.example.com
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Content-Length: 224
* upload completely sent off: 224 out of 224 bytes
< HTTP/1.1 302 Found
< Server: nginx
< Date: Mon, 13 Jul 2020 14:22:54 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 213
< Connection: keep-alive
< Keep-Alive: timeout=20
< Cache-Control: private
< Location: /api/payer/auth?sessionToken=e744a95992fa405ba10662bbc6908d6bedd48a73cc0d45d589f4ef2f7d7a0b88
< Set-Cookie: returnUrl=http://example.com/returnurl.php; path=/
<
* Ignoring the response-body
* Connection #0 to host api.dev.walletone.com left intact
* Issue another request to this URL: 'https://api.dev.example.com/auth?sessionToken=e744b95992fa405ba10662bbc6908d6b7dd48a73cc0d45d589f4ef2f7d7a0b88'
* Switch from POST to GET
* Found bundle for host api.dev.example.com: 0x5649fd243480 [can pipeline]
* Re-using existing connection! (#0) with host api.dev.example.com
* Connected to api.dev.example.com (188.186.236.44) port 443 (#0)
> POST /auth?sessionToken=e744b95992fa405ba10662bbc6908d6b7dd48a73cc0d45d589f4ef2f7d7a0b88 HTTP/1.1
Host: api.dev.example.com
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
< HTTP/1.1 411 Length Required
< Server: nginx
< Date: Mon, 13 Jul 2020 14:22:54 GMT
< Content-Type: text/html; charset=us-ascii
< Content-Length: 344
< Connection: keep-alive
< Keep-Alive: timeout=20
<
* Connection #0 to host api.dev.example.com left intact
My code is:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $path);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, Array (
"Content-Type: application/x-www-form-urlencoded",
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
));
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $curl_method);
curl_setopt($ch, CURLOPT_POSTFIELDS, $order_data);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_STDERR, $verbose);
$response = curl_exec($ch);
curl_close($ch);
Set the content-length in the header, which would be set to the string length strlen() of $order_data
curl_setopt($ch, CURLOPT_HTTPHEADER, Array (
"Content-Type: application/x-www-form-urlencoded",
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Content-Length: ". strlen($order_data)
));
you can also debug this by checking out curl_setopt($ch, CURLINFO_HEADER_OUT, true); which makes curl_getinfo() include the request's headers in its output.
The problem was in using curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $curl_method). Curl tryed to swithc to GET, like mostly browsers do, but cannot. Use curl_setopt($ch, CURLOPT_POST, 1); indeed.
We want to communicate to the 3rd party API for which we are using curl from linux terminal. The curl is -
curl -X POST \
\
-H 'Authorization: Bearer ' \
-H 'Content-Type: application/json'
When we fire this curl then we are getting expected response.
However, when we try to do this from PHP script then we are getting error as -
HTTP ERROR 500
PHP Code snippet is -
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, <URL>);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
//curl_setopt($ch, CURLOPT_POSTFIELDS,'');
curl_setopt($ch, CURLOPT_VERBOSE,true);
$headers = array();
$headers[] = 'Authorization: Bearer <token>';
$headers[] = 'Content-Type: application/json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
echo $result;
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
curl_close($ch);
?>
When verbose mode is on then response received is -
* Trying <IP>...
* Connected to <URL> (<IP>) port 443 (#0)
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:#STRENGTH
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server did not agree to a protocol
* Server certificate:
* subject: OU=Domain Control Validated; CN=* <domain>
* start date: Dec 17 10:41:01 2017 GMT
* expire date: Dec 17 10:41:01 2020 GMT
* subjectAltName: <URL> matched
* issuer: C=US; ST=Arizona; L=Scottsdale; O=GoDaddy.com, Inc.; OU=http://certs.godaddy.com/repository/; CN=Go Daddy Secure Certificate Authority - G2
* SSL certificate verify ok.
> POST /app/auth HTTP/1.1
Host: <URL>
Accept: */*
Authorization: Bearer <Token>
Content-Type: application/json
Expect: 100-continue
< HTTP/1.1 500 Request failed.
< Cache-Control: must-revalidate,no-cache,no-store
< Content-Type: text/html;charset=iso-8859-1
< Date: Wed, 08 Jan 2020 04:39:23 GMT
< Content-Length: 252
< Connection: keep-alive
* HTTP error before end of send, stop sending
<
* Closing connection 0
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>Error 500 Request failed.</title>
</head>
<body><h2>HTTP ERROR 500</h2>
<p>Problem accessing /app/auth. Reason:
<pre> Request failed.</pre></p>
</body>
</html>
Please note that Ihave replaced actual URL,IP and token while posting the question here.
To make sure that there are no issues with the PHP curl we used curl-to-PHP code generator utility to generate code ( http://incarnate.github.io/curl-to-php/).
Can someone please help me and let me know what might be going wrong.
To avoid «500 error» (for example) be sure to:
set proper "Referer: " header if needed, with
curl_setopt(CURLOPT_REFERER, 'ref page');
set proper "User-Agent: " header, with
curl_setopt(CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)');
I'm trying to get JSON from my IOT application. I can post data to my IOT application so my connection is ok but cant get a response. I only get a not allowed error.
I use this code:
$ch = curl_init();
curl_setopt($ch, CURLOPT_VERBOSE, true);
$verbose = fopen('php://temp', 'w+');
curl_setopt($ch, CURLOPT_STDERR, $verbose);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL,$endpoint_url);
$result = curl_exec($ch);
if ($result === FALSE) {
printf("cUrl error (#%d): %s<br>\n", curl_errno($ch),
htmlspecialchars(curl_error($ch)));
}
curl_close($ch);
rewind($verbose);
$verboseLog = stream_get_contents($verbose);
echo "Verbose information:\n<pre>", htmlspecialchars($verboseLog), "</pre>\n";
But all I get back is the following:
Verbose information:
* Hostname integrations.thethingsnetwork.org was found in DNS cache
* Trying 13.69.184.129...
* Connected to integrations.thethingsnetwork.org (13.69.184.129) port 443
(#0)
* ALPN, offering http/1.1
* Cipher selection:
ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:#STRENGTH
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
* subject: CN=integrations.thethingsnetwork.org
* start date: Jan 31 12:04:08 2019 GMT
* expire date: May 1 12:04:08 2019 GMT
* subjectAltName: integrations.thethingsnetwork.org matched
* issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
* SSL certificate verify ok.
> GET /ttn-eu/api/v2/down/secret/test?key=secret HTTP/1.1
Host: integrations.thethingsnetwork.org
Accept: */*
< HTTP/1.1 405 Method Not Allowed
< Server: nginx/1.13.7
< Date: Wed, 20 Mar 2019 15:33:10 GMT
< Content-Type: text/plain; charset=utf-8
< Content-Length: 0
< Connection: keep-alive
<
* Connection #0 to host integrations.thethingsnetwork.org left intact
How can I get the data?
You are not specifying the Request type in your curl request which automatically defaults it to a GET one. Add the following to your code.
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
I am developing a system that can check if a remote server has or not SSL enabled
My input is a simple URL, Example http://www.stackoverflow.com
How can i do that ?
Using CURL invoke given url
Get all header from curl
read header info returned by Curl response
For curl library and its curl function, Go through http://php.net/manual/en/book.curl.php
There are multiple ways to do this. The first one is the easiest, just try to retrieve the data (e.g. using file_get_contents()) from the specified URL with the HTTPS protocol. You get a timeout? That most likely means SSL/TLS is not supported.
Another one is to open a socket to port 443. Get a timeout? Again, that most likely means secure connections are not supported.
Another approach, which gives you more information, is to shell invoke something like OpenSSL (openssl s_client -connect example.com:443). But that's a lot more work, not always allowed, much more failure prone and you need to parse the result yourself.
An untested (no server available currently) and most likely not completely working (I haven't written a line of PHP in a few years) example for the first solution:
<?php
error_reporting(E_ALL);
$hasSsl = false;
if ($_SERVER["REQUEST_METHOD"] == "post")
{
// I hate error suppressing, but it's just a quick 'n dirty example!
$data = #file_get_contents($_POST["url"]);
$hasSsl = (strlen($data) != 0);
}
// Do something with $hasSsl
?>
<!doctype HTML>
<body>
<form method="post">
<p>
<input type="uri" name="url">
<input type="submit">
</p>
</form>
</body>
$sslEnabled = (isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) != 'off') ? TRUE : FALSE;
EDIT 1
use curl: change http by https
send HEAD Request to this url
read the http response : if 200 then ssl is enabled
EDIT 2
input : http://www.stackoverflow.com
naive approach : $url = str_replace ("http", "https", $input);
preapring curl : with HTTP
$ch = curl_init ($url);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_VERBOSE, 0);
curl_setopt ($ch, CURLOPT_HEADER, 1); // i want to read header response from server
curl_setopt ($ch, CURLOPT_CUSTOMREQUEST, 'HEAD'); // my request is HEAD
curl_setopt ($ch, CURLOPT_NOBODY, true); // i don't need to get body response : it is better for me and for the remote server
curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, true); // to follow the location when http response is 301
curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, 10); // if ssl is not enabled, my connection can take a lot of time so i will wait only for 10 seconds otherwise SSL is not enabled : you can enhance this value
curl_exec ( $ch ) ;
$header = curl_getinfo($ch, CURLINFO_HEADER_OUT);
var_dump ($header_size);
the result is : (i got 2 http response, you should take the last one)
* About to connect() to proxy XXX.YYY.ZZZ.AAA port N (#0)
* Trying XXX.YYY.ZZZ.AAA... * connected
* Connected to XXX.YYY.ZZZ.AAA (XXX.YYY.ZZZ.AAA) port N (#0)
* ******************************************
> HEAD http://www.stackoverflow.com HTTP/1.1
* ******************************************
Host: www.stackoverflow.com
Pragma: no-cache
Accept: */*
Proxy-Connection: Keep-Alive
< HTTP/1.0 301 Moved Permanently
< Content-Length: 148
< Content-Type: text/html; charset=UTF-8
< Location: http://stackoverflow.com/
< Date: Wed, 13 May 2015 11:01:07 GMT
* ******************************************
* ******************************************
* ******************************************
* ******************************************
< Proxy-Connection: keep-alive
* Connection #0 to host XXX.YYY.ZZZ.AAA left intact
* Issue another request to this URL: 'http://stackoverflow.com/'
* Examining connection #0 for reuse
* Re-using existing connection! (#0) with host XXX.YYY.ZZZ.AAA
* Connected to XXX.YYY.ZZZ.AAA (XXX.YYY.ZZZ.AAA) port N (#0)
* ******************************************
> HEAD http://stackoverflow.com/ HTTP/1.1
* ******************************************
Host: stackoverflow.com
Pragma: no-cache
Accept: */*
Proxy-Connection: Keep-Alive
< HTTP/1.0 200 OK
< Cache-Control: public, no-cache="Set-Cookie", max-age=52
< Content-Length: 238748
< Content-Type: text/html; charset=utf-8
< Expires: Wed, 13 May 2015 11:02:01 GMT
< Last-Modified: Wed, 13 May 2015 11:01:01 GMT
< Vary: *
< X-Frame-Options: SAMEORIGIN
* ******************************************
< Set-Cookie: prov=bb4ad145-d7ed-4d40-8e02-43976c589c10; domain=.stackoverflow.com; expires=Fri, 01-Jan-2055 00:00:00 GMT; path=/; HttpOnly
< Date: Wed, 13 May 2015 11:01:08 GMT
* ******************************************
* ******************************************
* ******************************************
* ******************************************
< Proxy-Connection: keep-alive
* Connection #0 to host XXX.YYY.ZZZ.AAA left intact
* Closing connection #0
header response : with HTTPS (stackoverflow has not SLL on port 443)
* About to connect() to www.stackoverflow.com port 443 (#0)
* Trying 198.252.206.16... * Timeout
* connect() timed out!
* Closing connection #0
NOTE : you have to enable php_curl.dll in your php.ini file and restart your server
https://stackoverflow.com/a/21848415/524743
use the extension loaded check!
http://php.net/manual/en/function.extension-loaded.php
if(!extension_loaded('openssl')) {
throw new Exception('This app needs the Open SSL PHP extension.');
}
Or that one https://stackoverflow.com/a/7304205/524743
if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') {
// SSL connection
}
URL Working fine in Browser after accepting the exception , but not working in curl.
My code is as follows :::
PHP CODE :
<?php
$str1 = "https://50.60.70.80/servlet/API";
$url = $str1."?".$_SERVER['QUERY_STRING'];
echo $url;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt( $ch , CURLOPT_SSL_VERIFYHOST, true);
$data = curl_exec($ch);
echo curl_errno($ch);
if (curl_errno($ch)) {
echo 'Error: ' . curl_error($ch);
}
else {
echo 'Success: '.$data;
}
curl_close($ch);
?>
URL : https://50.60.70.80/servlet/API?userName=Test&password=pwd&message=My_Message&mobile=5555558888
Error getting while using through command line with "-k" and "-v":
***** About to connect() to 50.60.70.80 port 443 (#0)
* Trying 50.60.70.80... connected
* Connected to 50.60.70.80 (50.60.70.80) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* warning: ignoring value of ssl.verifyhost
* skipping SSL peer certificate verification
* SSL connection using TLS_DHM_RSA_W1TH_AES_128_CBC_SEA
* Server certificate:
* subject: E=abcd#mnmn.com,OU=lelna,O=teledna
* start date: Mar 01 09:51:25 2013 GMT
* expire date: Mar 01 09:51:25 2014 GMT
* common name: (nil)
* issuer: E=abcd#mnmn.com,OU=lelna,O=teledna
> GET /servlet/API?UserName=Test HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.14.3.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2
> Host: 50.60.70.80
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< Pragma: no-cache
< Cache-Control: no-store
< Expires: Thu, 01 Jan 1970 00:00:00 GMT
< Transfer-Encoding: chunked
< Date: Thu, 08 Aug 2013 16:38:57 GMT
<
status=FAILED,transid=4526698561,reasoncode=201
* Connection #0 to host 50.60.70.80 left intact
* Closing connection #0****
Can anybody help ?
I am using following versions ::
PHP Version -- 5.3.3
CURL Version -- 7.19.7
Using Apache
You need to add this
EDITED :
curl_setopt( $ch ,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');