How to Post Form Data to 3rd Party Server After Go

2019-08-26 01:59发布

问题:

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>

回答1:

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']='GERONIMO@EXAMPLE.COM';

        $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';
    }
}


回答2:

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>