Keys
Add FMK_SITE_KEY and FMK_SECRET to .env and map them in config/services.php under 'fitmykb' as site_key and secret.
FitMyKB Verify
A small validation rule checks the token with siteverify, so any form request can require it next to its other rules.
Add FMK_SITE_KEY and FMK_SECRET to .env and map them in config/services.php under 'fitmykb' as site_key and secret.
The rule posts the token to siteverify with Laravel's HTTP client and fails the field when the check doesn't pass.
<?php // app/Rules/FitMyKBCaptcha.php
namespace App\Rules;
use Closure;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Support\Facades\Http;
class FitMyKBCaptcha implements ValidationRule
{
public function validate(string $attribute, mixed $value, Closure $fail): void
{
$reply = Http::asForm()->timeout(5)->post('https://fitmykb.com/captcha/siteverify', [
'secret' => config('services.fitmykb.secret'),
'response' => (string) $value,
]);
if (! $reply->json('success')) {
$fail('Please complete the check.');
}
}
}Load api.js in the Blade view, place the box in the form, and require fmk-captcha-response with the rule.
{{-- resources/views/register.blade.php --}}
<script src="https://fitmykb.com/captcha/api.js" async defer></script>
<form method="POST" action="/register">
@csrf
<input name="email" type="email">
<div class="fmk-captcha" data-sitekey="{{ config('services.fitmykb.site_key') }}"></div>
<button>Create account</button>
</form>
// In the controller
$request->validate([
'email' => ['required', 'email'],
'fmk-captcha-response' => ['required', new \App\Rules\FitMyKBCaptcha],
]);In a FormRequest, put the same rule in rules(). Livewire forms can read the token from the request in the action that saves.
In feature tests, swap the rule with Http::fake for the siteverify address, so tests never call the network.