Google reCaptcha helps to protect the website against spam and bot submissions. It is mainly applied to login, registration, contact us, and add comment forms.
There are 2 versions of Google reCaptcha –
- v2 – User needs to select images based on the question.
- v3 – This is an invisible type of captcha.
In this tutorial, I show how you can add google recpatcha v2 to your form with validation in the CodeIgniter 4 project.
Contents
- Get Google reCaptcha keys
- Create variables in .env
- Enable CSRF
- Create custom validation for reCaptcha
- Create Controller
- Routes
- Create View
- Output
- Conclusion
1. Get Google reCaptcha keys
You can skip this step if you already registered for Google reCAPTCHA v2 and have site and secret keys.
- Navigate to the following link for registering the website for reCaptcha.
- Following page will display. Here, enter a label, select reCAPTCHA v2 from the reCAPTCHA type, and then “I’m not a robot” Checkbox if not selected. Specify domain names where you want to use and you can also specify localhost if you want to test it on your system.
- Click the Submit button.
- After submitting a new page display that has a site and secret keys.
- Copy the keys.
2. Create variables in .env
- Open
.env
file which is available at the project root.
NOTE – If dot (.) not added at the start then rename the file to .env.
- Here, define 2 variables for storing the captcha site and secret keys –
GOOGLE_RECAPTCHA_SITEKEY = 6LfGNWsjAAAAAL8pSk9JRfoe4StH6GJxAm9qc38g GOOGLE_RECAPTCHA_SECRETKEY = 6LfGNWsjAAAAAGOVwDKbCLNm_c9NS49GNOsO1Ol-
3. Enable CSRF
- Again open
.env
file. - Remove # from the start of the
security.tokenName
,security.headerName
,security.cookieName
,security.expires
,andsecurity.regenerate
. - I update the
security.tokenName
value with'csrf_hash_name'
. With this name read CSRF hash. You can update it with any other value. - If you don’t want to regenerate CSRF hash after each request then set
security.regenerate = false
.
security.tokenName = 'csrf_hash_name' security.headerName = 'X-CSRF-TOKEN' security.cookieName = 'csrf_cookie_name' security.expires = 7200 security.regenerate = true
- Open
app/Config/Filters.php
file. - Uncomment
'csrf'
in'before'
if commented.
// Always applied before every request public $globals = [ 'before' => [ // 'honeypot', 'csrf', // 'invalidchars', ], 'after' => [ 'toolbar', // 'honeypot', // 'secureheaders', ], ];
4. Create custom validation for reCaptcha
- Create a new
CaptchaValidation.php
file inapp/Config/
folder. - Create
CaptchaValidation
class and averifyrecaptcha()
method. - This method name –
verifyrecaptcha
use for calling while defining validation in the controller. - Read secret key from
.env
and assign to$secretkey
. Here,$str
has recaptcha response. - If
$str
is not empty then send the request to –
"https://www.google.com/recaptcha/api/siteverify?secret=".$secretkey."&response=".$str."&remoteip=".$_SERVER['REMOTE_ADDR']
for verification. Here, pass $secreteky
,$str
, and $_SERVER['REMOTE_ADDR']
.
- If response is successfully returned then return
true
otherwise, returnfalse
and assign error message to$error
variable.
Completed Code
<?php namespace Config; class CaptchaValidation{ public function verifyrecaptcha(string $str, ?string &$error = null): bool { $secretkey = getenv('GOOGLE_RECAPTCHA_SECRETKEY'); if(($str) && !empty($str)) { $response = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=".$secretkey."&response=".$str."&remoteip=".$_SERVER['REMOTE_ADDR']); $responseData = json_decode($response); if($responseData->success) { // Verified return true; } } $error = "Invalid captacha"; return false; } }
Update Validation.php
For using the above-created Validation need to update the Validation.php
file.
- Open
app/Config/Validation.php
file. - Include
Config\CaptchaValidation
class. - Specify
CaptchaValidation::class
in$ruleSets
Array.
Completed Code
<?php namespace Config; use CodeIgniter\Config\BaseConfig; use CodeIgniter\Validation\CreditCardRules; use CodeIgniter\Validation\FileRules; use CodeIgniter\Validation\FormatRules; use CodeIgniter\Validation\Rules; use Config\CaptchaValidation; // Custom reCAPTCHA validation class Validation extends BaseConfig { // -------------------------------------------------------------------- // Setup // -------------------------------------------------------------------- /** * Stores the classes that contain the * rules that are available. * * @var string[] */ public $ruleSets = [ Rules::class, FormatRules::class, FileRules::class, CreditCardRules::class, CaptchaValidation::class, // Custom reCAPTCHA validation ]; /** * Specifies the views that are used to display the * errors. * * @var array<string, string> */ public $templates = [ 'list' => 'CodeIgniter\Validation\Views\list', 'single' => 'CodeIgniter\Validation\Views\single', ]; // -------------------------------------------------------------------- // Rules // -------------------------------------------------------------------- }
5. Create Controller
- Create
PagesController
Controller.
php spark make:controller PagesController
- Create 2 methods –
- index() – Load
index
view. - submitcontactus() – This method calls on form submit.
- index() – Load
Define validation. Here, for g-recaptcha-response
specify verifyrecaptcha
with required.
If validation is failed then return to the page with the validation response otherwise set SESSION flash message and redirect to route('/')
.
Completed Code
<?php namespace App\Controllers; use App\Controllers\BaseController; class PagesController extends BaseController{ public function index(){ return view('index'); } public function submitcontactus(){ // Validation $input = $this->validate([ 'name' => 'required', 'email' => 'required', 'subject' => 'required', 'message' => 'required', 'g-recaptcha-response' => 'required|verifyrecaptcha', ],[ 'g-recaptcha-response' => [ 'required' => 'Please verify captcha', ], ]); if (!$input) { // Not valid $data['validation'] = $this->validator; return redirect()->back()->withInput()->with('validation', $this->validator); }else{ // Set Session session()->setFlashdata('message', 'Submitted Successfully!'); session()->setFlashdata('alert-class', 'alert-success'); } return redirect()->route('/'); } }
6. Routes
- Open
app/Config/Routes.php
file. - Here, create 2 routes –
- /
- page/submitcontactus – Handle form submit.
$routes->get('/', 'PagesController::index'); $routes->post('page/submitcontactus', 'PagesController::submitcontactus');
7. Create View
- Create
index.php
file inapp/Views/
folder. - Include recaptcha js in
<head >
section –
<script src='https://www.google.com/recaptcha/api.js'></script>
- Create a simple contact
<form >
. Set action url to<?=site_url('page/submitcontactus')?>
. - Add Google reCaptcha container. Here,
<div >
hasclass="g-recaptcha"
anddata-sitekey="<?= getenv('GOOGLE_RECAPTCHA_SITEKEY') ?>"
.
<div class="g-recaptcha" data-sitekey="<?= getenv('GOOGLE_RECAPTCHA_SITEKEY') ?>"></div>
Completed Code
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Add Google reCAPTCHA v2 to form in CodeIgniter 4</title> <!-- Bootstrap CSS --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" > <!-- reCAPTCHA JS--> <script src='https://www.google.com/recaptcha/api.js'></script> </head> <body> <div class="container"> <div class="row"> <div class="col-md-6 mt-5" style="margin: 0 auto;"> <?php // Display Response if(session()->has('message')){ ?> <div class="alert <?= session()->getFlashdata('alert-class') ?>"> <?= session()->getFlashdata('message') ?> </div> <?php } ?> <h2 class="mb-4">Contact US</h2> <?php $validation = \Config\Services::validation(); ?> <form method="post" action="<?=site_url('page/submitcontactus')?>"> <?= csrf_field(); ?> <div class="form-group mb-4"> <label class="control-label col-sm-2" for="name">Name:</label> <div class="col-sm-10"> <input type="text" class="form-control" id="name" placeholder="Enter Name" name="name" value="<?= old('name') ?>"> </div> <!-- Error --> <?php if( $validation->getError('name') ) {?> <div class='text-danger mt-2'> * <?= $validation->getError('name'); ?> </div> <?php }?> </div> <div class="form-group mb-4"> <label class="control-label col-sm-2" for="email">Email:</label> <div class="col-sm-10"> <input type="email" class="form-control" id="email" placeholder="Enter Email" name="email" value="<?= old('email') ?>"> </div> <!-- Error --> <?php if( $validation->getError('email') ) {?> <div class='text-danger mt-2'> * <?= $validation->getError('email'); ?> </div> <?php }?> </div> <div class="form-group mb-4"> <label class="control-label col-sm-2" for="subject">Subject:</label> <div class="col-sm-10"> <input type="text" class="form-control" id="subject" placeholder="Enter Subject" name="subject" value="<?= old('subject') ?>" > </div> <!-- Error --> <?php if( $validation->getError('subject') ) {?> <div class='text-danger mt-2'> * <?= $validation->getError('subject'); ?> </div> <?php }?> </div> <div class="form-group mb-4"> <label class="control-label col-sm-2" for="message">Message:</label> <div class="col-sm-10"> <textarea class="form-control" id="message" name="message"><?= old('message') ?></textarea> </div> <!-- Error --> <?php if( $validation->getError('message') ) {?> <div class='text-danger mt-2'> * <?= $validation->getError('message'); ?> </div> <?php }?> </div> <div class="form-group mb-4"> <!-- reCAPTCHA --> <div class="g-recaptcha" data-sitekey="<?= getenv('GOOGLE_RECAPTCHA_SITEKEY') ?>" ></div> <!-- Error --> <?php if( $validation->getError('g-recaptcha-response') ) {?> <div class='text-danger mt-2'> * <?= $validation->getError('g-recaptcha-response'); ?> </div> <?php }?> </div> <div class="form-group "> <div class="col-sm-offset-2 col-sm-10"> <button type="submit" class="btn btn-info">Submit</button> </div> </div> </form> </div> </div> </div> </body> </html>
8. Output
9. Conclusion
I hope this tutorial helps you to successfully add Google reCaptcha v2 to your page.
You can also this tutorial if you want to know Google reCAPTCHA v3 implementation in CodeIgniter 4.
If you found this tutorial helpful then don't forget to share.