0

I'm just desperately trying to make it work... Been sitting on this for a good 4 hours
I tried many many solutions from google, I have no idea what to do now so posting here is my last resort.
I also tried using recaptcha v2 which would honestly be a better option but I gave up on it before because nothing worked when I tried to add it for a button.
Here is my code:

index.php

<?php
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Get Key</title>
    <link rel="stylesheet" href="style.css">
    <script src="index.js"></script>
    <script
      src="https://code.jquery.com/jquery-3.4.1.min.js"
      integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
      crossorigin="anonymous"></script>
      <script src="https://www.google.com/recaptcha/api.js?render=6LexkIoiAAAAAGxENEyPQ-e5sVubBaKlX9HSVM31" async defer></script>
  </head>
</head>
<body>
    <div class="center">
        <form id="getkeyForm" action="captchahandler.php" method="POST">
            <h3>Please complete the linkvertises to get the key</h3>
            <h3>Linkvertise (1/4)</h3>
            <input type="submit" name="submit" onclick="prnt()" id="submitBtn" class="submitBtn" value="Submit">
        </form>
    </div>
</body>
</html>



captchahandler.php

<?php
define("RECAPTCHA_V3_SECRET_KEY", 'my-secret-key');
  
$token = $_POST['token'];
$action = $_POST['action'];
  
// call curl to POST request
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"https://www.google.com/recaptcha/api/siteverify");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(array('secret' => RECAPTCHA_V3_SECRET_KEY, 'response' => $token)));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
$arrResponse = json_decode($response, true);
  
// verify the response
if($arrResponse["success"] == '1' && $arrResponse["action"] == $action && $arrResponse["score"] >= 0.5) {
    // valid submission
    // go ahead and do necessary stuff
    echo 'SUCCESS';
    echo $response;
} else {
    // spam submission
    // show error message
    echo 'FAIL';
    echo $response;
}
?>



index.js

$('#getkeyForm').submit(function(event) {
    event.preventDefault();

    grecaptcha.ready(function() {
        grecaptcha.execute('6LdLk7EUAAAAAEWHuB2tabMmlxQ2-RRTLPHEGe9Y', {action: 'getkey'}).then(function(token) {
            $('#getkeyForm').prepend('<input type="hidden" name="token" value="' + token + '">');
            $('#getkeyForm').prepend('<input type="hidden" name="action" value="getkey">');
            $('#getkeyForm').unbind('submit').submit();
        });;
    });
});
3
  • The first step is to make sure that the form is submitting what you think it is. You can do this with var_dump($_POST); at the top of captchahandler.php to make sure all of your form inputs are being submitted.
    – aynber
    Commented Oct 17, 2022 at 17:15
  • I have no inputs, I only have a button
    – nnaem
    Commented Oct 17, 2022 at 17:22
  • But the button is appending the inputs to the form. So are those being passed in?
    – aynber
    Commented Oct 17, 2022 at 17:22

1 Answer 1

1

I'm not familiar with jQuery so opted for vanilla Javascript instead as I was finding that the form was not submitting properly when I tested the above. This may have been down to the use of submit as the name of the button - a common source of errors and not always an obvious one.

The flow of the app is as follows:

  • The button is clicked and the form is submitted but prevented from actually completing the submission because of event.preventDefault()
  • The Google Recaptcha execute method is called to verify the keys etc
  • The response from Google is used to populate a new form input element (token)
  • The form is then submitted programmatically to the original form action ( here all in one page rather than separate captchahandler.php script )
  • The token is used with other arguments to create a unique querystring / url which is used in a GET request for simplicity using file_get_contents
  • The JSON response is analysed to determine success/failure and if successful you want to return a key of some sort based upon interpretation of the question/code.
  • Generate a message for the user which will be shown once the form has been submitted.

<?php
    
    $result=false;
    
    define('PUBKEY','6LftN...............10nqi8');
    define('PRIVKEY','6LftN...................Bw_UJc');
    
    if( $_SERVER['REQUEST_METHOD']=='POST' && isset(
        $_POST['token'],
        $_POST['action']
    )){
        $baseurl = 'https://www.google.com/recaptcha/api/siteverify';
        $secret = PRIVKEY;
        /*
            You do not need to use curl, simply issue
            a GET request with the full querystring using 
            `file_get_contents` is perfectly OK.
        */
        $url=sprintf(
            '%s?secret=%s&response=%s&remoteip=%s', 
            $baseurl, 
            $secret, 
            $_POST['token'], 
            $_SERVER['REMOTE_ADDR']
        );
        $json = json_decode( file_get_contents( $url ) );
        if( intval( $json->success )===1 && floatval( $json->score ) > 0.5 ){
            
            http_response_code(200);
            
            # Fetch the key...this is just as an example!
            $key=hash_hmac('sha256',date('Y-m-d'),PRIVKEY);
            
            $result='Your secret, one-time code is: '.$key;
        }else{
            #handle the challenge failure somehow.
            $result='Challenge Failed';         
        }
    }
?>
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Get Key</title>
        
        <!--
        <link rel="stylesheet" href="style.css">
        <script src="index.js"></script>
        <script
            src="https://code.jquery.com/jquery-3.4.1.min.js"
            integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
            crossorigin="anonymous">
        </script>
        -->
        
        <script>
            <?php
                printf('const _PUBKEY="%s";', PUBKEY );
            ?>
            
            document.addEventListener('submit',e=>{
                
                e.preventDefault();
                
                grecaptcha.ready(()=>{
                    grecaptcha.execute( _PUBKEY, { action: 'getkey' } )
                        .then(r=>{
                            
                            let form=document.forms.linkvurts;
                            
                            let input=document.createElement('input');
                                input.name='token'
                                input.type='hidden';
                                input.value=r;
                            form.appendChild( input );
                            
                                input=document.createElement('input');
                                input.name='action'
                                input.type='hidden';
                                input.value='getkey';
                            form.appendChild( input );
                            form.submit();
                        })
                })
                
                return false;
            })
            
            
            const prnt=()=>{
                console.info('print')
            }
        </script>
        <script src="https://www.google.com/recaptcha/api.js?render=6LftN...............10nqi8" async defer></script>
      </head>
    </head>
    <body>
        <div class="center">
            <form name='linkvurts' id="getkeyForm" method="POST">
                <h3>Please complete the linkvertises to get the key</h3>
                <h3>Linkvertise (1/4)</h3>
                <!--
                    remove the name='submit' or rename as something other than `submit`!!!!
                -->
                <input type="submit" onclick="prnt()" class="submitBtn" value="Submit" />
            </form>
            <?php
                if( !empty( $result ) )echo $result;
            ?>
        </div>
    </body>
</html>
3
  • I can't express how grateful I am for this. However I'm having one issue: Uncaught Error: Invalid site key or not loaded in api.js: 6LexkIoiAAAAAGxENEyPQ-e5sVubBaKlX9HSVM31 I have inputted the correct public key (site key right?) and private key
    – nnaem
    Commented Oct 18, 2022 at 15:47
  • Nevermind, I'm an idiot, I didn't enter the site key in the api.js?render load
    – nnaem
    Commented Oct 18, 2022 at 15:53
  • 1
    I hope this helped you solve your conundrum.... good luck with further coding adventures Commented Oct 18, 2022 at 21:26

Not the answer you're looking for? Browse other questions tagged or ask your own question.