I have a problem with google reCaptcha.
Here is my php code:
$secret = 'SECRET_KEY';
$response = $_POST['g-recaptcha-respone'];
$remoteip = $_SERVER['REMOTE_ADDR'];
$url = "https://www.google.com/recaptcha/api/siteverify?secret=$secret&response=$response&remoteip=$remoteip";
$result_json = file_get_contents($url);
$resulting = json_decode($result_json, true);
print_r($resulting);
if($resulting['success']) {
//Success
}
input of print_r is: Array ( [success] => [error-codes] => Array ( [0] => missing-input-response ) )
How to solve this problem?
Thanks for answers
Please note : g-recaptcha-respone != g-recaptcha-response
Google reCatcha API you might need to specify additional parameters to the file_get_contents function call, setting the context options specifically for SSL (If site has SSL).
// If submitted check response
if ($_POST["g-recaptcha-response"]) {
// Input data
$secret = 'SECRET_KEY';
$response = $_POST['g-recaptcha-response'];
$remoteip = $_SERVER['REMOTE_ADDR'];
$url = "https://www.google.com/recaptcha/api/siteverify";
$post_data = http_build_query(
array(
'secret' => $secret,
'response' => $response,
'remoteip' => $remoteip
)
);
$options=array(
// If site has SSL then
'ssl'=>array(
// In my case its /etc/ssl/certs/cacert.pem
'cafile' => '/path/to/cacert.pem',
'verify_peer' => true,
'verify_peer_name' => true,
),
'http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $post_data
)
);
$context = stream_context_create( $options );
$result_json = file_get_contents( $url, false, $context );
$resulting = json_decode($result_json, true);
if($resulting['success']) {
//Success
} else {
// action for no response
}
At least on ubuntu - If site has SSL
cd /usr/local/share/ca-certificates
sudo curl http://curl.haxx.se/ca/cacert.pem -o cacert.crt
sudo update-ca-certificates
sudo update-ca-certificates –fresh
and your cafile and path will be
capath=/etc/ssl/certs/
cafile=/etc/ssl/certs/cacert.pem
In my case I needed to add two extra parameters ('', '&') in this call:
http_build_query(array(
'secret' => $secret,
'response' => $response,
'remoteip' => $remoteip
), '', '&');
This error happened to me because I had two instances of the ReCaptcha element on my page (one for mobile views, one for desktop). As soon as I removed one of them this error stopped.
I'm not able to comment so I'm going to answer here. I copied my code which works perfectly and btw $_POST['g-recaptcha-respone'], are you sure your inputs name is g-recaptcha-respone?
$secret = 'SECRET-KEY';
$response = $_POST['g-recaptcha-response'];
$ip = $_SERVER['REMOTE_ADDR'];
$dav = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=".$secret."&response=".$response."&remoteip=".$ip);
$res = json_decode($dav,true);
if ($res['success']) {
die(json_encode(0));
} else {
die(json_encode(1));
}
Just a note on this, you should be sending all your params via POST not GET (see https://developers.google.com/recaptcha/docs/verify#api_request). Use something like cURL to help make the request.
Related
Sorry for the messy code in advance. I want to write a code which returns me infos from the official Blizzard API, which I can then print out on my homepage. The code doesn't throw any errors but it doesn't print out something either. For Starters:
I would also prefer using CURL, but my homepage is on a Wordpress Hosting Site and I don't know how to install the CURL Library that way
allow_furl_open is on
$url = "https://eu.battle.net/oauth/token";
$data = array('grant_type' => 'client_credentials');
//HTTP options
$opts = array('http' =>
array(
'method' => 'POST',
'header' => array ('Content-type: multipart/form-data', 'Authorization: Basic ' .
base64_encode("$client_id:$client_pass")),
'content' => json_encode($data)
)
);
//Do request
$context = stream_context_create($opts);
$json = file_get_contents($url, false, $context);
$result = json_decode($json, true);
$accessToken = $json['access_token'];
$tokenURL = "https://us.api.blizzard.com/data/wow/token/?namespace=dynamic-eu";
$opts2 = array('http' =>
array(
'method' => 'POST',
'header' => array('Content-type: multipart/form-data', 'Authorization: Bearer ' . $accessToken),
)
);
$context2 = stream_context_create($opts2);
$json2 = file_get_contents($tokenURL,false,$context2);
$result2 = json_decode($json2, true);
$tokenprice = $result2['price'];
echo "<p>Tokenpreis:" .$tokenprice. "</p>";
I didn't add the $client_id and $client_pass into the code snippet, but this exists obviously. I used this PHP CURL Snippet as template. And this is a short explanation on blizzard's site on how is this supposed to work:
Anyone got any ideas what went wrong? I am really out of ideas here and would love anyone who could help.
Thanks in advance
Based on the curl example from the linked API docs, the content type should be application/x-www-form-urlencoded, and so for the initial request to https://eu.battle.net/oauth/token you should be able to follow the example here.
In your case this will look something like:
$url = 'https://eu.battle.net/oauth/token';
$data = array('grant_type' => 'client_credentials');
$opts = array(
'http' => array(
'method' => 'POST',
'header' => array (
'Content-type: application/x-www-form-urlencoded',
'Authorization: Basic ' . base64_encode("$client_id:$client_pass")
),
'content' => http_build_query($data)
)
);
$context = stream_context_create($opts);
$json = file_get_contents($url, false, $context);
Also, in your code you are storing the raw result from the initial request in $json, then the decoded array in $result, but attempting to get the access_token from the initial request, instead of the decoded array.
Formerly i used XML way to get data from external API. Now, internal company policy orders to use JSON to communicate with API. I know what data i should send in request and how data i'll get back but i have no idea how to call with API by JSON.
My PHP server is localhost.
Let JSON API be located https://api.example.com/service-api and i'm sure it works fine.
Request
{"action":"authorization", "args":{"username":"firstname#dev.com","password":"qpujy676"}}
Callback
{"status":"OK", "token":"8hsa77hh687y3sbdha7ah3dajknfa93"}
I found example but i dont know what is Http_client(), what is it role and what it will do.
$http = new Http_Client();
$http->setUri('https://api.example.com/service-api');
$postdata = array(
'action' => 'authorization',
'args' => array(
'username' => 'firstname#dev.com',
'password' => 'qpujy676',
)
);
if (CRYPT_KEY_API) { //if encrypted data
$postdata ['rand'] = md5(time() . rand(2303, 85500));
$postdata = json_encode($postdata);
$postdata = Crypt::encrypt($postdata);
} else {
$postdata = json_encode($postdata);
}
$http->setRawData($postdata, 'application/json');
$response = $http->request(POST);
if ($response->isSuccessful()) {
$responseData = $response->getBody();
if (CRYPT_KEY_API) { //if encrypted data
$responseData = Crypt::decrypt($responseData);
}
$results = json_decode($responseData, true);
} else {
$error_message = "<p>Error</p>\n";
$error_message .= "HTTP Status: " . $response->getStatus() . "\n";
$error_message .= "HTTP Headers:\n";
$responseHeaders = $response->getHeaders();
foreach ($responseHeaders as $responseHeaderName => $responseHeaderValue) {
$error_message .= "$responseHeaderName: $responseHeaderValue\n";
}
throw new Exception($error_message);
}
Practically i need only exemplary http_client class to solve my problem :-) Especially
setRawData($postdata, 'application/json')
request(POST)
getBody()
I creared method autorization_test(), that supposedly should response with external API. Supposedly, because it output is:
Warning:
file_get_contents(https://api.example.com/service-api):
failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found in
C:\xampp\htdocs\prestashop1611\modules\miniwa\miniwa.php on line 180
Error
public function authorization_test()
{
$domain = MINIWA_DOMAIN;
$username = 'tester#user.com';
$password = '12345';
$postData = array(
'action' => 'authorization',
'args' => array(
'domain' => $domain,
'username' => $username,
'password' => $password,
),
);
$postData = json_encode($postData);
//$postData = Crypt::encrypt($postData);
$context = stream_context_create(array(
'http' => array(
// http://www.php.net/manual/en/context.http.php
'method' => 'POST',
'header' => 'Content-Type: application/json',
'content' => $postData,
)
));
// Send the request
$response = file_get_contents('https://api.example.com/service-api', FALSE, $context);
// Check for errors
if($response === FALSE){
die('Error');
}
//$response= Crypt::decrypt($response);
// Decode the response
$responseData = json_decode($response, TRUE);
// send the output data to view
$smarty->assign(array(
'json_decoded_output' => $responseData,
));
return $smarty;
Why there's no positive output?
Here you have whole documentation:
https://pear.php.net/manual/en/package.http.http-client.http-client-summary.php
API was disabled, now is OK, code is right.
I have what I think is correctly written code yet whenever I try and call it I'm getting permission denied from Google.
file_get_contents(https://www.googleapis.com/urlshortener/v1/url): failed to open stream: HTTP request failed! HTTP/1.0 403 Forbidden
This isn't a rate limit or anything as I currently have zero ever used...
I would have thought this is due to an incorrect API key but I've tried resetting it a number of times. There isn't some downtime while the API is first applied is there?
Or am I missing a header setting or something else just as small?
public function getShortUrl()
{
$longUrl = "http://example.com/";
$apiKey = "MY REAL KEY IS HERE";
$opts = array(
'http' =>
array(
'method' => 'POST',
'header' => "Content-type: application/json",
'content' => json_encode(array(
'longUrl' => $longUrl,
'key' => $apiKey
))
)
);
$context = stream_context_create($opts);
$result = file_get_contents("https://www.googleapis.com/urlshortener/v1/url", false, $context);
//decode the returned JSON object
return json_decode($result, true);
}
It seems I need to manually specify the key in the URL
$result = file_get_contents("https://www.googleapis.com/urlshortener/v1/url?key=" . $apiKey, false, $context);
This now works. There must be something funny with how the API inspects POST for the key (or lack of doing so).
Edit: For anyone in the future this is my complete function
public static function getShortUrl($link = "http://example.com")
{
define("API_BASE_URL", "https://www.googleapis.com/urlshortener/v1/url?");
define("API_KEY", "PUT YOUR KEY HERE");
// Used for file_get_contents
$fileOpts = array(
'key' => API_KEY,
'fields' => 'id' // We want ONLY the short URL
);
// Used for stream_context_create
$streamOpts = array(
'http' =>
array(
'method' => 'POST',
'header' => [
"Content-type: application/json",
],
'content' => json_encode(array(
'longUrl' => $link,
))
)
);
$context = stream_context_create($streamOpts);
$result = file_get_contents(API_BASE_URL . http_build_query($fileOpts), false, $context);
return json_decode($result, false)->id;
}
I have this function here:
public static function call($action, array $args)
{
$post_args = array(
'action' => $action,
'args' => $args
);
$stream = json_encode($post_args);
$headers = array(
'Content-type: application/json',
'Accept: application/json',
'Expect:'
);
$userpwd = self::$_user.':'.sha1(sha1(self::$_pass));
$ch = curl_init();
$args = array(
CURLOPT_URL => self::$_url,
CURLOPT_FOLLOWLOCATION => TRUE,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_POST => TRUE,
CURLOPT_POSTFIELDS => $stream,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_USERPWD => $userpwd
);
curl_setopt_array($ch, $args);
$res = curl_exec($ch);
$data = json_decode($res, true);
if (isset($data) === TRUE
&& empty($data) === FALSE
) {
$res = $data;
}
return $res;
}//end call()
and at the URL where I'm posting, I'm just doing:
echo file_get_contents('php://input');
but getting nothing, even though I do post data. What could be the problem? I'm at a dead end.
Also, why do I need CURLOPT_FOLLOWLOCATION set to TRUE when I'm just posting to a simple virtual host URL on my local machine, not doing any redirects.
EDIT:
tried redoing it with fopen like so:
public static function call($action, array $args)
{
$post_args = array(
'action' => $action,
'args' => $args
);
$stream = json_encode($post_args);
$userpwd = self::$_user.':'.sha1(sha1(self::$_pass));
$opts = array(
'http' => array(
'method' => 'POST',
'header' => array(
"Authorization: Basic ".base64_encode($userpwd),
"Content-type: application/json"
),
'content' => $stream
)
);
$context = stream_context_create($opts);
$res = '';
$fp = fopen(self::$_url, 'r', false, $context);
if($fp){
while (!feof($fp)){
$res .= fread($fp, 128);
}
}
return $res;
}//end call()
no success. The connection works with curl and with fopen, since I pass the status along with result (which is just the php://input stream). Any ideas?
Can you be sure about that curl_exec function ends successfully. Also, why don't you use fopen for this purpose. I have written a JSON RPC client and server. I'm sending requests with fopen, and it works perfect.
$httpRequestOptions =
array(
'http'=>array(
'method'=>'POST',
'header'=>'Content-type: application/json',
'content'=>$requestJSON
)
);
$context = stream_context_create($httpRequestOptions);
// send request
if($fileHandler = #fopen($serverURL, 'r', false, $context)){
I'm not writing the rest. You can use this code I have written.
Found out the problem.
I was calling http://localhost/api, since I thought that it would load the index.php automatically, and then I was going to change the default file name for the folder.
The problem was that I didn't add index.php at the end - I should've called http://localhost/api/index.php.
This way it worked with cURL and with fopen.
Any ideas how to call the API without revealing the filename?
I want to make HTTPS request through PHP to a server and get the response.
something similar to this ruby code
http = Net::HTTP.new("www.example.com", 443)
http.use_ssl = true
path = "uri"
resp, data = http.get(path, nil)
Thanks
this might work, give it a shot.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
// Set so curl_exec returns the result instead of outputting it.
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Get the response and close the channel.
$response = curl_exec($ch);
curl_close($ch);
for more info, check
http://unitstep.net/blog/2009/05/05/using-curl-in-php-to-access-https-ssltls-protected-sites/
To open HTTPS stream I could only work it out using both HTTP and SSL context options…
Thus something like:
<?php
$postdata = http_build_query(
array(
'var1' => 'some content',
'var2' => 'doh'
)
);
$opts = array(
'ssl' => array(
'verify_peer' => false,
'verify_peername' => false
// Instead ideally use
// 'cafile' => 'path Certificate Authority file on local filesystem'
),
'http' => array(
'method' => 'POST',
'header' =>
'Content-type: application/x-www-form-urlencoded'."\r\n".
''
'content' => $postdata
)
);
$context = stream_context_create($opts);
$result = file_get_contents('https://example.com/submit.php', false, $context);
// A Good friend
var_dump($http_response_header);
?>
The Zend Framework has a nice component called Zend_Http_Client which is perfect for this kind of transaction.
Under the hood it uses curl to make requests, but you'll find Zend_Http_Client has a much nicer interface to work with and is easier to configure when you want to add custom headers or work with responses.
If all you want to do is retrieve the page contents with minimal work, you may be able to do the following, depending on your server's configuration:
$data = file_get_contents('https://www.example.com/');
Example how to use HttpRequest to post data and receive the response:
<?php
//set up variables
$theData = '<?xml version="1.0"?>
<note>
<to>my brother</to>
<from>me</from>
<heading>hello</heading>
<body>this is my body</body>
</note>';
$url = 'http://www.example.com';
$credentials = 'user#example.com:password';
$header_array = array('Expect' => '',
'From' => 'User A');
$ssl_array = array('version' => SSL_VERSION_SSLv3);
$options = array(headers => $header_array,
httpauth => $credentials,
httpauthtype => HTTP_AUTH_BASIC,
protocol => HTTP_VERSION_1_1,
ssl => $ssl_array);
//create the httprequest object
$httpRequest_OBJ = new httpRequest($url, HTTP_METH_POST, $options);
//add the content type
$httpRequest_OBJ->setContentType = 'Content-Type: text/xml';
//add the raw post data
$httpRequest_OBJ->setRawPostData ($theData);
//send the http request
$result = $httpRequest_OBJ->send();
//print out the result
echo "<pre>"; print_r($result); echo "</pre>";
?>
There are 2 examples, GET and POST methods, but they both require the HttpRequest library to be included.
If you don't have the HttpRequest library included, kindly check this answer on how to include it: HttpRequest not found in php
GET example:
<?php
$r = new HttpRequest('http://example.com/feed.rss', HttpRequest::METH_GET);
$r->setOptions(array('lastmodified' => filemtime('local.rss')));
$r->addQueryData(array('category' => 3));
try {
$r->send();
if ($r->getResponseCode() == 200) {
file_put_contents('local.rss', $r->getResponseBody());
}
} catch (HttpException $ex) {
echo $ex;
}
?>
Post Example
<?php
$r = new HttpRequest('http://example.com/form.php', HttpRequest::METH_POST);
$r->setOptions(array('cookies' => array('lang' => 'de')));
$r->addPostFields(array('user' => 'mike', 'pass' => 's3c|r3t'));
$r->addPostFile('image', 'profile.jpg', 'image/jpeg');
try {
echo $r->send()->getBody();
} catch (HttpException $ex) {
echo $ex;
}
?>