How to implement reCAPTCHA v2

Hi,

Im trying to add a reCAPTCHA v2 to my livewire form component.
I’ve found a laravel package: https://github.com/biscolab/laravel-recaptcha and begann to integrate it into livewire.

After the installation i can show the reCAPTCHA on the form component. Unfortunately i have some troubles with the validation.

I need to validate this attribute: ‘g-recaptcha-response’. The problem is i can’t add such atttribute name to the class property.

Does anyone else have a problem like that?

This is my component:

    public $customerId;
    public $isCustomer = false;
    //not working
    public $g-recaptcha-response;
    public function register()
    {
        $validatedData = $this->validate([
            'customerId' => 'required|min:3',
            'isCustomer' => 'boolean',
            'g-recaptcha-response' => 'recaptcha',
        ]);

    }

This is my view:

<form method="POST" class="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4" wire:submit.prevent="register">
        @csrf
        <div class="mb-4">
            <label class="block text-gray-700 text-sm font-semibold mb-1"
                   for="isCustomer"
            >
                I'm a customer
                <input class=""
                       id="isCustomer"
                       type="checkbox"
                       wire:model.lazy="isCustomer"
                >
            </label>
            @error('isCustomer') <p class="text-red-500 text-xs italic">{{ $message }}</p> @enderror

        </div>
        <div class="mb-4">
            <label class="block text-gray-700 text-sm font-semibold mb-1"
                   for="customerId"
            >
                Customer ID
            </label>
            <input class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline @error('customerId') border-red-500 @enderror"
                   id="customerId"
                   type="text"
                   placeholder="customerId"
                   wire:model.lazy="customerId"
            >
            @error('customerId') <p class="text-red-500 text-xs italic">{{ $message }}</p> @enderror
        </div>
        <div class="mb-4">
            {!! htmlFormSnippet() !!}
        </div>
        <button type="submit" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline">
            Save
        </button>
    </form>

I’m using Laravel 7.7.1 and newest Livewire 1.0.12.

1 Like

I’m looking at his as well. I think there is no other way than figure out a way to add wire:model=“nice_name_without_dashes” to the right element in the generated HTML.

UPDATE 1:
What I have done so far is: added a hidden input field.
<input type="hidden" id="my-captcha" value="test" wire:model="captcha">
To the script link I just added an onload param. According to this link.

After that I created under the form a script with an onload callback function and putted the success grecaptcha.getResponse to the hidden input value.

<script type="text/javascript">
        var onloadCallback = function() {
            document.getElementById('my-captcha').value=grecaptcha.getResponse()
        };
    </script>  

Unfortunately this is not working as expected. The class prop $captcha is null.
And a the second problem is, after submiting the form the reCAPTCHA is gone…

UPDATE 2:
with this approach I can set a gcaptcha response to a class property.
<button type="submit" wire:click="$set('captcha', grecaptcha.getResponse())">

The problem now is, when server re-renders the component and responds with the new HTML the recaptcha completly disappears.

Can you use wire:ignore around the recaptcha checkbox?

How did you manage to resolve the ‘timeout-or-duplicate’ error issue when submitting the form more than once?

Hey, @7ammer
Take a look at this thread