Top Menu

To prevent bots from registering into your web app you can add a Captcha. In this tutorial, I will show you how to add Google reCAPTCHA to the register page in laravel 9

Step 1. Custom Validation Rule

We will validate the recaptcha after submitting the form. So first, we will create a custom validation rule.

php artisan make:rule Recaptcha

This will create a file app/Rules/Recaptcha.php. In this rule we need to do:

  • Send an HTTP post request to Google to verify the captcha. We need to send the secret keyrecaptcha token, and user IP.
  • Check if the response is successful, and if the returned score is bigger then minimal is set.
  • If everything passes return true, otherwise return false.

app/Rules/Recaptcha.php

use Illuminate\Support\Facades\Http;
 
class Recaptcha implements Rule
{
    public function passes($attribute, $value)
    {
        $response = Http::asForm()->post("https://www.google.com/recaptcha/api/siteverify", [
                'secret' => config('services.recaptcha.secret_key'),
                'response' => $value,
                'ip' => request()->ip(),
        ]);
 
        if ($response->successful() && $response->json('success') && $response->json('score') > config('services.recaptcha.min_score')) {
            return true;
        }
 
        return false;
    }
 
    public function message()
    {
        return 'Failed to validate ReCaptcha.';
    }
}

We store values from Google reCAPTCHA into config/services.php:

return [
    // ...
    'recaptcha' => [
        'site_key' => env('RECAPTCHA_SITE_KEY'),
        'secret_key' => env('RECAPTCHA_SECRET_KEY'),
        'min_score' => env('RECAPTCHA_MIN_SCORE', .5),
    ],
];

Step 2. Prepare Layout for reCAPTCHA

To use reCAPTCHA we need to add some scripts.

resources/views/layouts/guest.blade.php:

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="csrf-token" content="{{ csrf_token() }}">
 
        <title>{{ config('app.name', 'Laravel') }}</title>
 
        <!-- Fonts -->
        <link rel="preconnect" href="https://fonts.bunny.net">
        <link href="https://fonts.bunny.net/css?family=figtree:400,500,600&display=swap" rel="stylesheet" />
 
        <!-- Scripts -->
        @vite(['resources/css/app.css', 'resources/js/app.js'])
        <script src="https://www.google.com/recaptcha/api.js?render={{ config('services.recaptcha.site_key') }}"></script> 
    </head>
    <body>
        <div class="font-sans text-gray-900 antialiased">
            {{ $slot }}
        </div>
 
        @stack('scripts') 
    </body>
</html>

resources/views/auth/register.blade.php:

<x-guest-layout>
    <form method="POST" action="{{ route('register') }}"> 
    <form method="POST" action="{{ route('register') }}" id="registerForm"> 
        @csrf
 
        // ...
 
    @push('scripts') 
        <script>
            grecaptcha.ready(function () {
                document.getElementById('registerForm').addEventListener("submit", function (event) {
                    event.preventDefault();
                    grecaptcha.execute('{{ config('services.recaptcha.site_key') }}', { action: 'register' })
                        .then(function (token) {
                            document.getElementById("recaptcha_token").value = token;
                            document.getElementById('registerForm').submit();
                        });
                });
            });
        </script>
    @endpush 
</x-guest-layout>

About The Author

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Close