dpayne
dpayne

Reputation: 273

How to Post Form Data to 3rd Party Server After Google Invisible reCaptcha Success?

I have what is probably a pretty basic question but am pretty new to PHP and form creation so hoping somebody can help me out.

We've got spam bots continuously submitting a one-field email form on our site, despite having the honeypot method in place, so am looking to use Google's Invisible reCaptcha to combat that.

I'm following the instructions in this helpful guide: https://www.pinnacleinternet.com/installing-invisible-recaptcha/ but where I'm getting stuck is, after the result is a success, I'd like to take the email address that was submitted via the form and then post it to a third party server (in this case, our marketing automation tool, Pardot).

Here is the Invisible reCaptcha code:

Front-end

<script>
function captchaSubmit(data) {
document.getElementsByClassName("invisible-recaptcha").submit();
}
</script>  

<form action="utils/recaptcha.php" method="post" class="pardot-email-form-handler invisible-recaptcha" novalidate>    
        <input class="one-field-pardot-form-handler" maxlength="80" name="email" size="20" type="email" placeholder="Enter Email Address" required="required" />
        <div style="position:absolute; left:-9999px; top: -9999px;">
          <label for="pardot_extra_field">Comments</label>
          <input type="text" id="pardot_extra_field" name="pardot_extra_field">
        </div>

        <button class="g-recaptcha" data-sitekey="anonymous" data-callback="captchaSubmit" type="submit" name="captchaSubmit">Submit</button>
    </form>

Back end:

<?php
    // reCaptcha info
    $secret = "anonymous";
    $remoteip = $_SERVER["REMOTE_ADDR"];
    $url = "https://www.google.com/recaptcha/api/siteverify";

    // Form info
    $email = $_POST["email"];
    $response = $_POST["g-recaptcha-response"];

    // Curl Request
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_POST, true);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_POSTFIELDS, array(
        'secret' => $secret,
        'response' => $response,
        'remoteip' => $remoteip
        ));
    $curlData = curl_exec($curl);
    curl_close($curl);

    // Parse data
    $recaptcha = json_decode($curlData, true);
    if ($recaptcha["success"])
        echo "Success!";
    else
        echo "Failure!";
?>

I had previously posted to Pardot using the code below but am now unclear on how to do that being that the initial post is to Google rather than Pardot. How would I post to Pardot after a success confirmation from Invisible reCaptcha?

<div class="nav-email-form">    
<form action="https://go.pardot.com/l/43312/2017-10-24/7dnr3n" method="post" class="pardot-email-form-handler" novalidate>

<input class="one-field-pardot-form-handler" maxlength="80" name="email" size="20" type="email" placeholder="Enter Email Address" required="required" />
<div style="position:absolute; left:-9999px; top: -9999px;">
  <label for="pardot_extra_field">Comments</label>
  <input type="text" id="pardot_extra_field" name="pardot_extra_field">
</div>

<button type="submit" name="submit">Submit</button>
</form>

Upvotes: 0

Views: 1660

Answers (2)

dpayne
dpayne

Reputation: 273

The below is what I ended up doing with the back-end code. Needs nicer success & error handling, and I only set SSL_VERIFYPEER to false because I was setting it up in a local environment, but it's tested and successfully posting to Pardot:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Results</title>
</head>
<body>
    <p>Thank you for entering the form.</p>

    <?php
        // reCaptcha info
        $secret = "anonymous";
        $remoteip = $_SERVER["REMOTE_ADDR"];
        $url = "https://www.google.com/recaptcha/api/siteverify";

        // Form info
        $email = $_POST["email"];
        $response = $_POST["g-recaptcha-response"];

        // Curl Request
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_POST, true);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, array(
            'secret' => $secret,
            'response' => $response,
            'remoteip' => $remoteip
            ));
        $curlData = curl_exec($curl);
        curl_close($curl);

        // Parse data
        $recaptcha = json_decode($curlData, true);

        if ($recaptcha["success"]) {
            echo "Success!";

            $pardotPost ='email='. $_POST["email"];
            $curl_handle = curl_init();
            $url = "anonymous";
            curl_setopt ($curl_handle, CURLOPT_URL,$url);
            curl_setopt($curl_handle, CURLOPT_POST, true);
            curl_setopt ($curl_handle, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt ($curl_handle, CURLOPT_POSTFIELDS, $pardotPost);
            curl_setopt( $curl_handle, CURLOPT_SSL_VERIFYPEER, false ); 
            $result = curl_exec ($curl_handle);
            curl_close ($curl_handle); 
        }   

        else {
            echo "Failure!";
        }
    ?>
</body>
</html>

Upvotes: 0

Professor Abronsius
Professor Abronsius

Reputation: 33813

As you are already using curl initially to process the captcha perhaps you should make a POST request using curl to Pardot upon a success response. You could perhaps try like this - not tested btw

function curl( $url=NULL, $options=NULL ){
    /*
        Download a copy of cacert.pem from
        https://curl.haxx.se/docs/caextract.html

        and then edit below as appropriate
    */
    $cacert='c:/wwwroot/cacert.pem';    #<-------- edit to suit own environment

    $res=array(
        'response'  =>  NULL,
        'info'      =>  array( 'http_code' => 100 ),
        'headers'   =>  NULL,
        'errors'    =>  NULL
    );
    if( is_null( $url ) ) return (object)$res;
    /* Initialise curl request object */
    $curl=curl_init();
    if( parse_url( $url,PHP_URL_SCHEME )=='https' ){
        curl_setopt( $curl, CURLOPT_SSL_VERIFYPEER, true );
        curl_setopt( $curl, CURLOPT_SSL_VERIFYHOST, 2 );
        curl_setopt( $curl, CURLOPT_CAINFO, $cacert );
    }
    /* Define standard options */
    curl_setopt( $curl, CURLOPT_URL,trim( $url ) );
    curl_setopt( $curl, CURLOPT_AUTOREFERER, true );
    curl_setopt( $curl, CURLOPT_FOLLOWLOCATION, true );
    curl_setopt( $curl, CURLOPT_FAILONERROR, true );
    curl_setopt( $curl, CURLOPT_HEADER, false );
    curl_setopt( $curl, CURLINFO_HEADER_OUT, false );
    curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true );
    curl_setopt( $curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36' );
    curl_setopt( $curl, CURLOPT_ENCODING, '' );
    /* Assign runtime parameters as options */
    if( isset( $options ) && is_array( $options ) ){
        foreach( $options as $param => $value ) curl_setopt( $curl, $param, $value );
    }
    /* Execute the request and store responses */
    $res=(object)array(
        'response'  =>  curl_exec( $curl ),
        'info'      =>  (object)curl_getinfo( $curl ),
        'errors'    =>  curl_error( $curl )
    );
    curl_close( $curl );
    return $res;
}

/*
    stage 1: POST to Google
    -----------------------
*/
$url='https://www.google.com/recaptcha/api/siteverify';
$params=array(
    'secret'    => $secret,
    'response'  => $_POST['g-recaptcha-response'],
    'remoteip'  => $_SERVER['REMOTE_ADDR']
);
$options=array(
    CURLOPT_POST        =>  true,
    CURLOPT_POSTFIELDS  =>  $params
);
$result=curl( $url, $options );
if( $result->info->http_code==200 ){

    $json=json_decode( $result->response );
    $status=$json->success;
    if( $status ){

        /*
            stage 2: POST to PARDOT
            -----------------------
        */

        $url='https://go.pardot.com/l/43312/2017-10-24/7dnr3n';

        /* fields within the PARDOT form */
        $_POST['pardot_extra_field']='';
        $_POST['submit']='';

        /* no need to send this field */
        unset( $_POST['g-recaptcha-response'] );

        /* this needs a value - but from where? */
        #$_POST['email']='[email protected]';

        $options=array(
            CURLOPT_POST        =>  true,
            CURLOPT_POSTFIELDS  =>  $_POST
        );
        $result=curl( $url, $options );
        if( $result->info->http_code==200 ){
            /* all good */
            header('Location: ?mailsent=true');
        } else {
            /* bogus */
        }
    } else {
        echo 'bogus';
    }
}

Upvotes: 1

Related Questions