Add Google reCAPTCHA v2 to form in CodeIgniter 4

Google reCaptcha is like a security guard for websites. It stops spam and robots from messing with things. It’s commonly used in places like when you log in, sign up, send a message, or leave a comment on a website.

There are two types of Google reCaptcha:

  1. v2 – You have to pick pictures to answer a question.
  2. v3 – This one works in the background, and you don’t even see it.

In this guide, I’ll show you how to add Google reCaptcha v2 to your form and make sure everything is secure in your CodeIgniter 4 project.

Add Google reCAPTCHA v2 to form in CodeIgniter 4


Table of Content

  1. Get Google reCAPTCHA keys
  2. Create variables in .env for storing reCAPTCHA keys
  3. Enable CSRF
  4. Create custom validation for reCAPTCHA
  5. Create Controller – Validate reCAPTCHA
  6. Create Routes
  7. Create View
  8. Output
  9. Conclusion

1. Get Google reCAPTCHA keys

Feel free to skip this part if you’ve already signed up for Google reCAPTCHA v2 and have your site and secret keys.

If not, follow these steps to register your website for reCAPTCHA:

  • 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.

Google reCAPTCHA v2 creation

  • After submitting a new page display that has a site and secret keys.

Google recaptcha v2 site and secret keys

  • Copy the keys.

2. Create variables in .env for storing reCAPTCHA keys

  • 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,and security.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 in app/Config/ folder.
  • Create CaptchaValidation class and a verifyrecaptcha() 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, return false 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 – Validate reCAPTCHA

  • Create PagesController Controller.
php spark make:controller PagesController
  • Create 2 methods –
    • index() – Load index view.
    • submitcontactus() – This method calls on form submit.

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. Create 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 in app/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 > has class="g-recaptcha" and data-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

View Output


9. Conclusion

Adding Google reCaptcha v2 to your forms in CodeIgniter 4 is a wise choice to make sure your website stays safe. By using this hidden security feature, you’re not just guarding your site from spam and robots but also making it easy for real users to use without any trouble.

Now that you know how to put reCaptcha v2 into your forms, your CodeIgniter 4 project is well-protected from unwanted problems. Keep it safe, keep it simple, and let your users have a spam-free time on your website.

You can also view 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.

Leave a Comment