Using a reCAPTCHA v2 "I am not a robot" checkbox in a Laravel application

Published on
Google reCAPTCHA

Google reCAPTCHA is an effective method for preventing bots from submitting forms in your application. reCAPTCHA is also delightfully easy to use. This guide shows how to add an "I'm not a robot" checkbox to a form, without using a composer package.

The code in this guide requires at least Laravel 7.

Step 1: Create a new site in the reCAPTCHA admin console

First, register your site in the reCAPTCHA admin console. This guide uses reCAPTCHA v2, with an "I'm not a robot" checkbox. Once you've registered your site, you'll get a site key and a secret key, put those in your .env file:

RECAPTCHA_V2_SITE_KEY="your-site-key"
RECAPTCHA_V2_SECRET_KEY="your-secret-key"

And use the values in your services.php config file:

'recaptcha' => [
    'site_key' => env('RECAPTCHA_V2_SITE_KEY'),
    'secret_key' => env('RECAPTCHA_V2_SECRET_KEY'),
],

Step 2: Add the reCAPTCHA checkbox to your blade view

Add the script tag to the <head> of the page you'll be using reCAPTCHA on:

<script src="https://www.google.com/recaptcha/api.js"></script>

Add the reCAPTCHA checkbox to your form:

<div class="g-recaptcha" data-sitekey="{{ config('services.recaptcha.site_key') }}"></div>

@error('g-recaptcha-response')
    <div class="text-red-500">{{ $message }}</div>
@enderror

Step 3: Validate the request in your controller

Lastly, validate the posted value and throw a validation exception if necessary:

$request->validate([
    'g-recaptcha-response' => 'required|string',
]);

$response = Http::asForm()->post('https://www.google.com/recaptcha/api/siteverify', [
    'secret' => config('services.recaptcha.secret_key'),
    'response' => $request->get('g-recaptcha-response'),
    'remoteip' => $request->getClientIp(),
]);

if (! $response->json('success')) {
    throw ValidationException::withMessages(['g-recaptcha-response' => 'Error verifying reCAPTCHA, please try again.']);
}

Step 4: Customize the validation attribute (optional)

By default, any error messages will show the "g-recaptcha-response" key to the user. You can make this prettier by adding the following to the attributes array of your validation.php language file:

'attributes' => [
    'g-recaptcha-response' => 'reCAPTCHA',
],