hCaptcha is alternative to popular Google reCaptcha. It is used to avoid any form from being spammed by bots.
Why I use hCaptcha?
According to hCaptcha website owner can earn income by using their captcha technology. For the moment, I haven’t earned anything yet from hCaptcha.
Demo hCaptcha Using PHP
For this demo, you just submit the form by clicking “Submit form”. If you do the the hCaptcha correctly you will get hCaptcha success if not hCaptcha fail.
How to Use hCaptcha Using PHP?
There are 3 Important steps:
- Add the hCaptcha widget to your webpage
- Verify the user response on server side
- Check the hCaptcha is ticked or no
Add the hCaptcha widget to your webpage
Add the script at HTML head
1 |
<script src="https://js.hcaptcha.com/1/api.js" async defer></script> |
Add the hCaptcha widget to your form
1 |
<div class="h-captcha" data-sitekey="your_site_key"></div> |
Verify the user response on server side
According to hCaptcha documentation, to use POST method to query their endpoint.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
$hcaptcha = 'https://hcaptcha.com/siteverify';//hcaptcha endpoint to verify the hcaptcha $response = $_POST['h-captcha-response']; $curlSession = curl_init(); curl_setopt($curlSession, CURLOPT_URL, $hcaptcha); curl_setopt($curlSession, CURLOPT_POST, 1); curl_setopt($curlSession, CURLOPT_POSTFIELDS, "response=".$response."&secret=YOUR_SECRET"); curl_setopt($curlSession, CURLOPT_BINARYTRANSFER, true); curl_setopt($curlSession, CURLOPT_RETURNTRANSFER, true); $jsonData = json_decode(curl_exec($curlSession)); curl_close($curlSession); |
Example of Success Response
If you print_r($json_data) will get the response below:
1 |
success e.g stdClass Object ( [success] => 1 [challenge_ts] => 2022-08-06T11:38:30.000000Z [hostname] => awesomegrasp.com ) |
You can do your programming logic based on the success status.
Check the hCaptcha is ticked or no
There 2 methods to do this
- Check the post value of ‘h-captcha-response’
- Use data-callback
Method #1: Check the post value of ‘h-captcha-response’
The problem with the form as it is, if a user doesn’t do the hCaptcha test, the user still can submit the form. So we need to add javascript checking on the client side to check whether the user has done the captcha test or no.
If you have done the captcha test, hCaptcha will send a string of response in the $_POST[‘h-captcha-response’]. If not this string will be empty.
1 2 3 4 5 6 7 |
jQuery('#submit').click(function(e){ var hcaptchaVal = jQuery('[name=h-captcha-response]').val(); if(hcaptchaVal == ""){ e.preventDefault(); //avoid the form from being submitted alert("Please complete the captcha test!"); } }); |
The Full Code for Method #1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
<?php if(isset($_POST)): $hcaptcha = 'https://hcaptcha.com/siteverify';//hcaptcha endpoint to verify the hcaptcha $response = $_POST['h-captcha-response']; $curlSession = curl_init(); curl_setopt($curlSession, CURLOPT_URL, $hcaptcha); curl_setopt($curlSession, CURLOPT_POST, 1); curl_setopt($curlSession, CURLOPT_POSTFIELDS, "response=".$response."&secret=YOUR_SECRET"); curl_setopt($curlSession, CURLOPT_BINARYTRANSFER, true); curl_setopt($curlSession, CURLOPT_RETURNTRANSFER, true); //* success e.g stdClass Object ( [success] => 1 [challenge_ts] => 2022-08-06T11:38:30.000000Z [hostname] => pengantin.com.my ) //* fail e.g stdClass Object ( [success] => [error-codes] => Array ( [0] => missing-input-secret [1] => invalid-input-response ) ) $jsonData = json_decode(curl_exec($curlSession)); curl_close($curlSession); endif; ?> <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script> <script src="https://js.hcaptcha.com/1/api.js" async defer></script> <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script> <title>hCaptcha Demo with PHP</title> </head> <body> <h1>hCaptcha Demo with PHP</h1> <?php if(isset($_POST) && sizeof($_POST) > 0): if($jsonData->success == 1): ?> <div class="alert alert-success" role="alert"> hCaptcha Success! </div> <?php else: ?> <div class="alert alert-danger" role="alert"> hCaptcha Fail! </div> <?php endif; ?> <?php endif;?> <form action="https://www.awesomegrasp.com/wp-content/demo/hcaptcha/" method="post"> <div class="mb-3"> <label for="exampleFormControlInput1" class="form-label">Email address</label> <input type="email" class="form-control" id="exampleFormControlInput1" placeholder="name@example.com"> </div> <div class="mb-3"> <label for="exampleFormControlTextarea1" class="form-label">Example textarea</label> <textarea class="form-control" id="exampleFormControlTextarea1" rows="3"></textarea> </div> <div class="col-12"> <div class="h-captcha" data-sitekey="YOUR_KEY"></div> </div> <div class="col-12"> <button class="btn btn-primary" type="submit" id="submit">Submit form</button> </div> </form> <script> jQuery('#submit').click(function(e){ var hcaptchaVal = jQuery('[name=h-captcha-response]').val(); if(hcaptchaVal == ""){ e.preventDefault(); //avoid the form from being submitted alert("Please complete the captcha test!"); } }); </script> </body> </html> |
Method #2 – Use data-callback
hCaptcha has a call back option for when the checkbox is checked.
1 |
<div class="h-captcha" data-callback="recaptchaCallback" data-sitekey="YOUR_KEY"></div> |
Disable the submit button
1 |
<button class="btn btn-primary" type="submit" id="submit" disabled>Submit form</button> |
Then create a callback function:
1 2 3 |
function recaptchaCallback() { jQuery('#submit').removeAttr('disabled'); }; |
The Full Code for Method #2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
<?php if(isset($_POST)): $hcaptcha = 'https://hcaptcha.com/siteverify';//hcaptcha endpoint to verify the hcaptcha $response = $_POST['h-captcha-response']; $curlSession = curl_init(); curl_setopt($curlSession, CURLOPT_URL, $hcaptcha); curl_setopt($curlSession, CURLOPT_POST, 1); curl_setopt($curlSession, CURLOPT_POSTFIELDS, "response=".$response."&secret=0x0927A785e4acAcc8aE08b67ee1496B1FB238f4a9"); curl_setopt($curlSession, CURLOPT_BINARYTRANSFER, true); curl_setopt($curlSession, CURLOPT_RETURNTRANSFER, true); //* success e.g stdClass Object ( [success] => 1 [challenge_ts] => 2022-08-06T11:38:30.000000Z [hostname] => pengantin.com.my ) //* fail e.g stdClass Object ( [success] => [error-codes] => Array ( [0] => missing-input-secret [1] => invalid-input-response ) ) $jsonData = json_decode(curl_exec($curlSession)); curl_close($curlSession); endif; ?> <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script> <script src="https://js.hcaptcha.com/1/api.js" async defer></script> <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script> <title>hCaptcha Demo with PHP</title> </head> <body> <h1>hCaptcha Demo with PHP</h1> <?php if(isset($_POST) && sizeof($_POST) > 0): if($jsonData->success == 1): ?> <div class="alert alert-success" role="alert"> hCaptcha Success! </div> <?php else: ?> <div class="alert alert-danger" role="alert"> hCaptcha Fail! </div> <?php endif; ?> <?php endif;?> <form action="https://www.awesomegrasp.com/wp-content/demo/hcaptcha/index2.php" method="post"> <div class="mb-3"> <label for="exampleFormControlInput1" class="form-label">Email address</label> <input type="email" class="form-control" id="exampleFormControlInput1" placeholder="name@example.com"> </div> <div class="mb-3"> <label for="exampleFormControlTextarea1" class="form-label">Example textarea</label> <textarea class="form-control" id="exampleFormControlTextarea1" rows="3"></textarea> </div> <div class="col-12"> <div class="h-captcha" data-callback="recaptchaCallback" data-sitekey="785cebcf-8402-408b-93b7-ca9a0b295b6b"></div> </div> <div class="col-12"> <button class="btn btn-primary" type="submit" id="submit" disabled>Submit form</button> </div> </form> <script> function recaptchaCallback() { jQuery('#submit').removeAttr('disabled'); }; </script> </body> </html> |