Skip to content

Instantly share code, notes, and snippets.

@muffycompo
Forked from rama-adi/README.MD
Created July 10, 2022 13:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save muffycompo/eb21a150f4bfaf1d2553e1331c49763d to your computer and use it in GitHub Desktop.
Save muffycompo/eb21a150f4bfaf1d2553e1331c49763d to your computer and use it in GitHub Desktop.
Use hCaptcha with any livewire component

Implement hCaptcha with Livewire Component

This is a simple way to implement hCaptcha with Livewire component.

NOTE: please read this carefully, and adjust variable names, etc to your use case

Setup

Before using this implementation, add their JS library first on your page

<script src="https://js.hcaptcha.com/1/api.js?hl=en" async defer></script>

Blade component

create a blade component (named anything. mine is: captcha.blade.php), and paste this:

(PLEASE READ ALL THE TODO!)

hcaptcha.blade.php

@props(['fieldName' => '', 'helperText' => ''])
<div
    x-data="{}"
    x-init="hcaptcha.render('h-captcha-{{$fieldName}}', {sitekey: 'TODO: add hCaptcha site key', callback: (e) => @this.set('{{$fieldName}}', e)})"
    class="space-y-2">
        <span class="text-sm font-medium leading-4 text-gray-700">
            CAPTCHA (anti-bot)
            <sup class="font-medium text-danger-700">*</sup>
        </span>
    <div wire:ignore id="h-captcha-{{$fieldName}}"></div>
    
    <!-- TODO: add your own input error handler -->
    <x-input-error :for="$fieldName"/>
    <p class="text-sm text-gray-600">{{$helperText}}</p>
</div>

If you don't have an error handler component, you can use this:

input-error.blade.php

@props(['for'])

@error($for)
<p {{ $attributes->merge(['class' => 'text-sm text-red-600']) }}>{{ $message }}</p>
@enderror

Final step is to add the validator. create one via php artisan make:rule HcaptchaValidator, then fill it with this

/**
     * Determine if the validation rule passes.
     *
     * @param string $attribute
     * @param mixed $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        $captchaResp = Http::asForm()->post('https://hcaptcha.com/siteverify', [
            'response' => $value,
            'secret' => env('HCAPTCHA_SECRET')
        ])->object();

        return $captchaResp->success;
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return 'error message here';
    }

Usage

Paste the component on your Livewire component... :)

Replace fieldName to the variable on your livewire's component php file livewire/any-component.blade.php

{{-- ...any field you have --}}
<x-captcha fieldName="fieldName" />

then on the method, you want to check if the token are valid and is not empty

public function someFunction(){
  $this->validate([ 'fieldName' => ['required', new HcaptchaValidator()] ])
}

Your livewire component should now be protected with hCaptcha

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment