帮助在自定义表单中验证Google reCAPTCHA

时间:2016-11-08 作者:rudtek

我正在尝试向我的自定义字段添加recaptcha。我在页面模板中创建了一个自定义表单,我认为这部分代码是相关的(不要担心API密钥是MerchantOne的公共演示API,所以它不是个人的):

// API Setup parameters
$gatewayURL = \'https://secure.merchantonegateway.com/api/v2/three-step\';
$APIKey = \'2F822Rw39fx762MaV7Yy86jXGTC7sCDy\';


// If there is no POST data or a token-id, print the initial shopping cart form to get ready for Step One.
if (empty($_POST[\'DO_STEP_1\']) && empty($_GET[\'token-id\'])) {

    print \'  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\';
    print \'
    <html>
      <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>Hansen Hunter Collect non-sensitive Customer Info</title>
      </head>
      <body>
      <p>We are pleased to offer the option for you to securely pay your Hansen Hunter & Co. invoice online.</p>
      <h2 class="pad">Invoice Details</h2>


        <form action="" method="post">
          <table>
          <tr><td><input type="text" name="shipping-address-first-name" placeholder="First Name" required></td></tr>
          <tr><td><input type="text" name="shipping-address-last-name" placeholder="Last Name" required></td></tr>
          <tr><td><input type="text" name="shipping-address-company" placeholder="Company" required></td></tr>
          <tr><td><input type="text" name="billing-address-phone" placeholder="Phone Number" required></td></tr>
          <tr><td><input type="text" name="billing-address-email" placeholder="Email Address" required></td></tr>
          <tr><td><input type="text" name="billing-invoice" placeholder="Invoice or Customer Number"></td></tr>
          <tr><td><input type="text" name="billing-amount" placeholder="Total Amount" required></td></tr>

          <tr><td><h4><br />Payment Information</h4></td></tr>

          <tr><td><input type="text" name="billing-address-first-name" placeholder="Cardholder First Name" required></td></tr>
          <tr><td><input type="text" name="billing-address-last-name" placeholder="Cardholder Last Name" required></td></tr>
          <tr><td><input type="text" name="billing-address-address1" placeholder="Address" required></td></tr>
          <tr><td><input type="text" name="billing-address-address2" placeholder="Address 2"></td></tr>
          <tr><td><input type="text" name="billing-address-city" placeholder="City" required></td></tr>
          <tr><td><input type="text" name="billing-address-state" placeholder="State" required></td></tr>
          <tr><td><input type="text" name="billing-address-zip" placeholder="Zip/Postal Code" required></td></tr>
          <tr><td><input type="text" name="billing-address-country" placeholder="Country" value="US" required></td></tr>
       <tr><td><div class="g-recaptcha" data-sitekey="6Lc2MiUTAAAAAGJeGAlku50gFi7hFKvIitP_-3e0"></div></td></tr>
          <tr><td><input type="submit" class="btn pad" value="Continue"><input type="hidden" name ="DO_STEP_1" value="true"></td></tr>
          </table>
        </form>

    \';
}else if (!empty($_POST[\'DO_STEP_1\'])) {

    // Initiate Step One: Now that we\'ve collected the non-sensitive payment information, we can combine other order information and build the XML format.
我已将此代码添加到我的函数中。php添加google api:

add_action(\'wp_head\',\'hook_recaptca\');

function hook_recaptca() {

    $output="<script src=\'https://www.google.com/recaptcha/api.js\'></script>";

    echo $output;
} 
这样就可以显示我的recaptcha。问题是它还没有得到验证。

我知道我还需要添加以下两段代码:

/**
 * Send a GET request to verify CAPTCHA challenge
 *
 * @return bool
 */
function captcha_verification() {

    $response = isset( $_POST[\'g-recaptcha-response\'] ) ? esc_attr( $_POST[\'g-recaptcha-response\'] ) : \'\';

    $remote_ip = $_SERVER["REMOTE_ADDR"];

    // make a GET request to the Google reCAPTCHA Server
    $request = wp_remote_get(
        \'https://www.google.com/recaptcha/api/siteverify?secret=your_secret&response=\' . $response . \'&remoteip=\' . $remote_ip
    );

    // get the request response body
    $response_body = wp_remote_retrieve_body( $request );

    $result = json_decode( $response_body, true );

    return $result[\'success\'];
}
以及

/**
 * Verify the CAPTCHA answer
 *
 * @param $user string login username
 * @param $password string login password
 *
 * @return WP_Error|WP_user
 */
function validate_captcha( $user, $password ) {

    if ( isset( $_POST[\'g-recaptcha-response\'] ) && !captcha_verification() ) {
        return new WP_Error( \'empty_captcha\', \'<strong>ERROR</strong>: Please retry CAPTCHA\' );
    }

    return $user;
}
但我不知道如何连接它们(使用什么钩子?)在我的表单中,如果用户未填写复选框,则会停止该用户。我看到了关于添加到登录表单、注册表单或注释的教程和问题,但似乎不知道如何添加到自定义表单。

如果有帮助,merchant one为其集成提供的整个php如下:

http://pastebin.com/mR5jf5B3

1 个回复
最合适的回答,由SO网友:sMyles 整理而成

发布表单后,需要立即验证reCAPTCHA。您只是在向同一页面发送帖子,因此应该在进行任何其他处理之前完成。

如果未验证,则需要再次显示表单,并显示错误消息。

function recaptcha_validated(){
    if( empty( $_POST[\'g-recaptcha-response\'] ) ) return FALSE;
    $response = wp_remote_get( add_query_arg( array(
                                              \'secret\'   => \'your_secret\',
                                              \'response\' => isset($_POST[\'g-recaptcha-response\']) ? $_POST[\'g-recaptcha-response\'] : \'\',
                                              \'remoteip\' => isset($_SERVER[\'HTTP_X_FORWARDED_FOR\']) ? $_SERVER[\'HTTP_X_FORWARDED_FOR\'] : $_SERVER[\'REMOTE_ADDR\']
                                          ), \'https://www.google.com/recaptcha/api/siteverify\' ) );

    if( is_wp_error( $response ) || empty($response[\'body\']) || ! ($json = json_decode( $response[\'body\'] )) || ! $json->success ) {
        //return new WP_Error( \'validation-error\',  __(\'reCAPTCHA validation failed. Please try again.\' ) );
        return FALSE;
    }

    return TRUE;
}

// reCAPTCHA data was POSTed, let\'s validate it!
if( ! empty( $_POST[\'DO_STEP_1\'] ) ){

    if( recaptcha_validated() === FALSE ){
        $recaptcha_error = TRUE;
        print \'<div class="error message">\' . __(\'reCAPTCHA failed, please try again.\') . \'</div>\';
    }

}

// Because we want to show the form again if there was an error, we first check if error var is set OR if DO_STEP_1 and token-id are empty
if ( isset( $recaptcha_error ) || ( empty($_POST[\'DO_STEP_1\']) && empty($_GET[\'token-id\']) ) ) {
     print \'<p>We are pleased to offer the option for you to securely pay your Hansen Hunter & Co. invoice online.</p>
      <h2 class="pad">Invoice Details</h2>    
        <form method="post">
          <table>
          <tr><td><input type="text" name="shipping-address-first-name" placeholder="First Name" required></td></tr>
          <tr><td><input type="text" name="shipping-address-last-name" placeholder="Last Name" required></td></tr>
          <tr><td><input type="text" name="shipping-address-company" placeholder="Company" required></td></tr>
          <tr><td><input type="text" name="billing-address-phone" placeholder="Phone Number" required></td></tr>
          <tr><td><input type="text" name="billing-address-email" placeholder="Email Address" required></td></tr>
          <tr><td><input type="text" name="billing-invoice" placeholder="Invoice or Customer Number"></td></tr>
          <tr><td><input type="text" name="billing-amount" placeholder="Total Amount" required></td></tr>

          <tr><td><h4><br />Payment Information</h4></td></tr>

          <tr><td><input type="text" name="billing-address-first-name" placeholder="Cardholder First Name" required></td></tr>
          <tr><td><input type="text" name="billing-address-last-name" placeholder="Cardholder Last Name" required></td></tr>
          <tr><td><input type="text" name="billing-address-address1" placeholder="Address" required></td></tr>
          <tr><td><input type="text" name="billing-address-address2" placeholder="Address 2"></td></tr>
          <tr><td><input type="text" name="billing-address-city" placeholder="City" required></td></tr>
          <tr><td><input type="text" name="billing-address-state" placeholder="State" required></td></tr>
          <tr><td><input type="text" name="billing-address-zip" placeholder="Zip/Postal Code" required></td></tr>
          <tr><td><input type="text" name="billing-address-country" placeholder="Country" value="US" required></td></tr>
       <tr><td><div class="g-recaptcha" data-sitekey="6Lc2MiUTAAAAAGJeGAlku50gFi7hFKvIitP_-3e0"></div></td></tr>
          <tr><td><input type="submit" class="btn pad" value="Continue"><input type="hidden" name="DO_STEP_1" value="true"></td></tr>
          </table>
        </form>

    \';
}
有什么理由不使用像Caldera Forms这样的插件而不是完全自定义的代码?该插件将为您处理其中的大部分内容,包括字段HTML输出、reCAPTCHA输出/验证,并仍然为您提供可在表单提交时调用的操作/挂钩,以允许您处理自定义代码:

https://wordpress.org/plugins/caldera-forms/

https://calderawp.com/downloads/caldera-forms-run-action/

https://wordpress.org/plugins/caldera-forms-run-action/

相关推荐

集成reCAPTCHA和wp_SignOn-需要什么?

我一直在使用wp_signon 长期在项目中://Do the actual login for WP User $creds = array(); $creds[\'user_login\'] = $skuser_name; $creds[\'user_password\'] = $skuser_pass; $creds[\'remember\'] = true; $user = wp_signon( $creds, false ); 这已经起作用很长