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:
- v2 – You have to pick pictures to answer a question.
- 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.
Table of Content
- Get Google reCAPTCHA keys
- Create variables in .env for storing reCAPTCHA keys
- Enable CSRF
- Create custom validation for reCAPTCHA
- Create Controller – Validate reCAPTCHA
- Create Routes
- Create View
- Output
- 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.
- After submitting a new page display that has a 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
,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 – Validate reCAPTCHA
- 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. 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 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
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.