2014-12-03 106 views
58

我剛剛設置新的谷歌recaptcha與複選框,它在網站上工作正常,但是我不知道如何在服務器端使用PHP做到這一點,我試圖使用舊的代碼在下面,但即使沒有使用recaptcha,表單也會被髮送。新的谷歌recaptcha與複選框服務器端php

require_once('recaptchalib.php'); 
$privatekey = "my key"; 
$resp = recaptcha_check_answer ($privatekey, 
     $_SERVER["REMOTE_ADDR"], 
     $_POST["recaptcha_challenge_field"], 
     $_POST["recaptcha_response_field"]); 

if (!$resp->is_valid) { 
$errCapt='<p style="color:#D6012C ">The CAPTCHA Code wasnot entered correctly.</p>';} 
+0

檢查它已經填寫。'如果(strlen的($ _ POST [ 'recaptcha_challenge_field'])> 0){}' – 2014-12-03 14:30:26

+0

謝謝你的迴應,但你可以給我更多的細節,請.. – Moatez 2014-12-03 15:06:55

+0

我剛剛在聯繫表單上實現了這一點。我建議使用新的谷歌提供的'recaptchalib.php'連同他們的例子在這個鏈接:https://github.com/google/ReCAPTCHA/tree/master/php – 2014-12-03 15:18:52

回答

83

這是溶液

的index.html

<html> 
    <head> 
    <title>Google recapcha demo - Codeforgeek</title> 
    <script src='https://www.google.com/recaptcha/api.js'></script> 
    </head> 
    <body> 
    <h1>Google reCAPTHA Demo</h1> 
    <form id="comment_form" action="form.php" method="post"> 
     <input type="email" placeholder="Type your email" size="40"><br><br> 
     <textarea name="comment" rows="8" cols="39"></textarea><br><br> 
     <input type="submit" name="submit" value="Post comment"><br><br> 
     <div class="g-recaptcha" data-sitekey="=== Your site key ==="></div> 
    </form> 
    </body> 
</html> 

verify.php

<?php 

     $email;$comment;$captcha; 
     if(isset($_POST['email'])) 
      $email=$_POST['email']; 
     if(isset($_POST['comment'])) 
      $comment=$_POST['comment']; 
     if(isset($_POST['g-recaptcha-response'])) 
      $captcha=$_POST['g-recaptcha-response']; 

     if(!$captcha){ 
      echo '<h2>Please check the the captcha form.</h2>'; 
      exit; 
     } 
     $response=json_decode(file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=YOUR SECRET KEY&response=".$captcha."&remoteip=".$_SERVER['REMOTE_ADDR']), true); 
     if($response['success'] == false) 
     { 
      echo '<h2>You are spammer ! Get the @$%K out</h2>'; 
     } 
     else 
     { 
      echo '<h2>Thanks for posting comment.</h2>'; 
     } 
?> 

http://codeforgeek.com/2014/12/google-recaptcha-tutorial/

+11

reCAPTCHA表單字段值直接連接到驗證URL中。攻擊者可以使用它在驗證請求上注入任意形式的參數,可能會繞過驗證碼。爲了解決這個問題,請像這樣清理captcha變量:'urlencode($ captcha)' – sffc 2015-10-01 08:19:24

+1

這段代碼不會編碼攻擊者可以使用的參數來破壞您的代碼。 – Paul 2016-03-25 07:53:16

+4

應按照[文檔](https://developers.google.com/recaptcha/docs/verify#api-request)中的指定發佈數據。此代碼使用GET方法。我會與[萊維特的答案](http://stackoverflow.com/a/30749288/412004)上的變化。 – 2016-06-23 11:59:14

2

在上面的例子。對我而言,這個if($response.success==false)的東西不起作用。這是正確的PHP代碼:

$url = 'https://www.google.com/recaptcha/api/siteverify'; 
$privatekey = "--your_key--"; 
$response = file_get_contents($url."?secret=".$privatekey."&response=".$_POST['g-recaptcha-response']."&remoteip=".$_SERVER['REMOTE_ADDR']); 
$data = json_decode($response); 

if (isset($data->success) AND $data->success==true) { 
      // everything is ok! 
} else { 
      // spam 
} 
+2

這是因爲您沒有將'true'作爲第二個參數傳遞給'json_decode'。默認情況下,'json_decode'返回一個對象(jsOn),但通過'true'將允許它返回一個數組。 – 2015-04-23 13:11:18

94

私鑰的安全

雖然這裏的答案是肯定的工作,他們用的是GET請求,這暴露了你的私鑰(即使https使用)。在Google Developers指定的方法是POST

驗證通過POST

function isValid() 
{ 
    try { 

     $url = 'https://www.google.com/recaptcha/api/siteverify'; 
     $data = ['secret' => '[YOUR SECRET KEY]', 
       'response' => $_POST['g-recaptcha-response'], 
       'remoteip' => $_SERVER['REMOTE_ADDR']]; 

     $options = [ 
      'http' => [ 
       'header' => "Content-type: application/x-www-form-urlencoded\r\n", 
       'method' => 'POST', 
       'content' => http_build_query($data) 
      ] 
     ]; 

     $context = stream_context_create($options); 
     $result = file_get_contents($url, false, $context); 
     return json_decode($result)->success; 
    } 
    catch (Exception $e) { 
     return null; 
    } 
} 

陣列語法:我使用了 「新的」 數組語法([]代替array(..))。如果你的PHP版本還不支持這個,你將不得不相應地編輯這3個數組定義(見註釋)。

返回值:該函數返回true如果用戶是有效的,false如果沒有,和null如果發生錯誤。您可以簡單地使用它,例如:if (isValid()) { ... }

+2

如果你需要*舊的數組語法*,將$ data = ...和$ options = ...聲明更改爲:'$ data = array('secret'=>'[Your SECRET KEY ]', 'response'=> $ _POST ['g-recaptcha-response'], 'remoteip'=> $ _SERVER ['REMOTE_ADDR']); $ options = array( 'http'=> array( 'header'=>「Content-type:application/x-www-form-urlencoded \ r \ n」, 'method'=>'POST' , 'content'=> http_build_query($ data) ); – Levit 2015-06-10 07:06:13

+2

; '])){ return false; }''' – Westy92 2016-11-28 03:47:18

+3

https URL實際上是加密的,因此即使使用GET請求也不公開https密鑰,請參閱:http://stackoverflow.com/questions/499591/are-https-urls-encrypted – 2016-12-08 14:06:10

5

簡單且最佳的解決方案如下。
的index.html

<form action="submit.php" method="POST"> 
    <input type="text" name="name" value="" /> 
    <input type="text" name="email" value="" /> 
    <textarea type="text" name="message"></textarea> 
    <div class="g-recaptcha" data-sitekey="Insert Your Site Key"></div> 
    <input type="submit" name="submit" value="SUBMIT"> 
</form> 

submit.php

<?php 
if(isset($_POST['submit']) && !empty($_POST['submit'])){ 
    if(isset($_POST['g-recaptcha-response']) && !empty($_POST['g-recaptcha-response'])){ 
    //your site secret key 
    $secret = 'InsertSiteSecretKey'; 
    //get verify response data 
    $verifyResponse = file_get_contents('https://www.google.com/recaptcha/api/siteverify?secret='.$secret.'&response='.$_POST['g-recaptcha-response']); 
    $responseData = json_decode($verifyResponse); 
    if($responseData->success){ 
     //contact form submission code goes here 

     $succMsg = 'Your contact request have submitted successfully.'; 
    }else{ 
     $errMsg = 'Robot verification failed, please try again.'; 
    } 
    }else{ 
    $errMsg = 'Please click on the reCAPTCHA box.'; 
    } 
} 
?> 

我發現從這裏這個參考和全教程 - Using new Google reCAPTCHA with PHP

1

要使用PHP的服務器端驗證。你需要考慮兩件最重要的事情。

1. $_POST['g-recaptcha-response'] 

2.$secretKey = '6LeycSQTAAAAAMM3AeG62pBslQZwBTwCbzeKt06V'; 

$verifydata = file_get_contents('https://www.google.com/recaptcha/api/siteverify?secret='.$secretKey.'&response='.$_POST['g-recaptcha-response']); 
     $response= json_decode($verifydata); 

如果你得到$ verifydata真正你做
詳細看看這個
Google reCaptcha Using PHP | Only 2 Step Integration

3

我喜歡萊維特的回答,並最終使用它。但我只想指出,以防萬一,有新的reCAPTCHA谷歌PHP庫:https://github.com/google/recaptcha

最新版本(現在1.1.2)支持作曲家,幷包含一個示例,您可以運行看看你是否正確配置了一切。

下面你可以看到自帶的這個官方圖書館(我爲清晰起見稍作修改)的例子中的一部分:

// Make the call to verify the response and also pass the user's IP address 
    $resp = $recaptcha->verify($_POST['g-recaptcha-response'], $_SERVER['REMOTE_ADDR']); 

    if ($resp->isSuccess()) { 
// If the response is a success, that's it! 
     ?> 
     <h2>Success!</h2> 
     <p>That's it. Everything is working. Go integrate this into your real project.</p> 
     <p><a href="/">Try again</a></p> 
     <?php 
    } else { 
// If it's not successful, then one or more error codes will be returned. 
     ?> 
     <h2>Something went wrong</h2> 
     <p>The following error was returned: <?php 
      foreach ($resp->getErrorCodes() as $code) { 
       echo '<tt>' , $code , '</tt> '; 
      } 
      ?></p> 
     <p>Check the error code reference at <tt><a href="https://developers.google.com/recaptcha/docs/verify#error-code-reference">https://developers.google.com/recaptcha/docs/verify#error-code-reference</a></tt>. 
     <p><strong>Note:</strong> Error code <tt>missing-input-response</tt> may mean the user just didn't complete the reCAPTCHA.</p> 
     <p><a href="/">Try again</a></p> 
    <?php 
    } 

希望它可以幫助別人。

10

我不是任何這些解決方案的粉絲。我用這個來代替:

$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL, "https://www.google.com/recaptcha/api/siteverify"); 
curl_setopt($ch, CURLOPT_HEADER, 0); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt($ch, CURLOPT_POST, 1); 
curl_setopt($ch, CURLOPT_POSTFIELDS, [ 
    'secret' => $privatekey, 
    'response' => $_POST['g-recaptcha-response'], 
    'remoteip' => $_SERVER['REMOTE_ADDR'] 
]); 

$resp = json_decode(curl_exec($ch)); 
curl_close($ch); 

if ($resp->success) { 
    // Success 
} else { 
    // failure 
} 

我要說,因爲你確保它被髮送到服務器,它不是做一個尷尬「的file_get_contents」呼叫,這是卓越的。這與此處描述的recaptcha 2.0兼容:https://developers.google.com/recaptcha/docs/verify

我發現這個更清潔。我發現大多數解決方案都是file_get_contents,當我覺得curl就足夠了。

+1

這是一個很好的工作解決方案,因爲在php.ini中禁用了'allow_url_fopen',因此無法使用file_get_contents()。適用於我。 +1。 – 2017-03-28 05:54:02

1

它與mattgen88類似,但我只是修復了CURLOPT_HEADER,並重新定義了它在domain.com主機服務器上工作的陣列。這個不適用於我的xampp localhost。那些小錯誤,但花了很長時間才弄清楚。此代碼已在domain.com託管上進行了測試。

$privatekey = 'your google captcha private key'; 

    $ch = curl_init(); 
    curl_setopt($ch, CURLOPT_URL, "https://www.google.com/recaptcha/api/siteverify"); 
    curl_setopt($ch, CURLOPT_HEADER, 'Content-Type: application/json'); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
    curl_setopt($ch, CURLOPT_POST, 1); 
    curl_setopt($ch, CURLOPT_POSTFIELDS, array(
     'secret' => $privatekey, 
     'response' => $_POST['g-recaptcha-response'], 
     'remoteip' => $_SERVER['REMOTE_ADDR'] 
    ) 
       ); 

    $resp = json_decode(curl_exec($ch)); 
    curl_close($ch); 

    if ($resp->success) { 
     // Success 
     echo 'captcha'; 
    } else { 
     // failure 
     echo 'no captcha'; 
    } 
1

這裏有一個簡單的例子。只記得提供谷歌API的secretKey和siteKey。

<?php 
$siteKey = 'Provide element from google'; 
$secretKey = 'Provide element from google'; 

if($_POST['submit']){ 
    $username = $_POST['username']; 
    $responseKey = $_POST['g-recaptcha-response']; 
    $userIP = $_SERVER['REMOTE_ADDR']; 
    $url = "https://www.google.com/recaptcha/api/siteverify?secret=$secretKey&response=$responseKey&remoteip=$userIP"; 
    $response = file_get_contents($url); 
    $response = json_decode($response); 
    if($response->success){ 
     echo "Verification is correct. Your name is $username"; 
    } else { 
     echo "Verification failed"; 
    } 
} ?> 

<html> 
<meta> 
    <title>Google ReCaptcha</title> 
</meta> 
<body> 
    <form action="index.php" method="post"> 
     <input type="text" name="username" placeholder="Write your name"/> 
     <div class="g-recaptcha" data-sitekey="<?= $siteKey ?>"></div> 
     <input type="submit" name="submit" value="send"/> 
    </form> 
    <script src='https://www.google.com/recaptcha/api.js'></script> 
</body>