Installation
composer require martian/laracaptcha
Publish the config file:
php artisan vendor:publish --provider="Martian\LaraCaptcha\LaraCaptchaServiceProvider"
Configuration
Edit .env with your chosen CAPTCHA service keys (e.g., HCAPTCHA_SITE_KEY, HCAPTCHA_SECRET_KEY or RECAPTCHA_SITE_KEY, RECAPTCHA_SECRET_KEY).
Configure .env and config/laracaptcha.php:
CAPTCHA_SERVICE=hcaptcha # or 'recaptcha_v2'/'recaptcha_v3'
First Use Case
Validate a form with CAPTCHA in Laravel's FormRequest:
use Martian\LaraCaptcha\Rules\Captcha;
public function rules()
{
return [
'captcha_token' => ['required', new Captcha],
];
}
Blade Integration Render CAPTCHA widget in Blade:
@captcha('hcaptcha') <!-- or 'recaptcha_v2'/'recaptcha_v3' -->
Outputs the HTML snippet (e.g., <div class="hcaptcha"></div>).
API Integration Validate CAPTCHA in API requests:
use Illuminate\Http\Request;
use Martian\LaraCaptcha\Facades\LaraCaptcha;
public function store(Request $request)
{
$validated = $request->validate([
'token' => ['required', function ($attribute, $value, $fail) {
if (!LaraCaptcha::verify($value)) {
$fail('CAPTCHA verification failed.');
}
}],
]);
}
Dynamic Service Switching Override the default service per request:
LaraCaptcha::setService('recaptcha_v3')->verify($token);
Multi-Step Forms Store the CAPTCHA token in a session or database for multi-step validation:
session(['captcha_token' => $request->token]);
Validate later:
$this->validate($request, ['token' => ['required', new Captcha(session('captcha_token'))]]);
Conditional Validation Skip CAPTCHA for trusted users (e.g., logged-in admins):
if (auth()->user()->isAdmin()) {
$rules['captcha_token'] = ['sometimes', new Captcha];
}
Custom Error Messages Localize or customize CAPTCHA errors:
$rules = ['token' => ['required', new Captcha]];
$messages = ['token.captcha' => 'Please complete the CAPTCHA to proceed.'];
$this->validate($request, $rules, $messages);
Token Expiry
session() or cache() to persist tokens briefly.Environment Mismatch
.env keys match the config/laracaptcha.php settings.php artisan config:clear after changes.API vs. Form Validation
0.9). Adjust thresholds in config:
'recaptcha_v3' => [
'threshold' => 0.5, // Default: 0.5
],
CORS Issues
Verification Failures
$response = LaraCaptcha::verify($token);
\Log::info('CAPTCHA Response', $response);
Silent Failures
'debug' => env('CAPTCHA_DEBUG', false),
Custom Services Extend the package to support other CAPTCHA providers:
// app/Providers/LaraCaptchaServiceProvider.php
public function register()
{
LaraCaptcha::extend('custom', function () {
return new CustomCaptchaService();
});
}
Middleware for API Protection Create middleware to auto-validate CAPTCHA on specific routes:
// app/Http/Middleware/ValidateCaptcha.php
public function handle($request, Closure $next)
{
if (!$request->has('token') || !LaraCaptcha::verify($request->token)) {
return response()->json(['error' => 'CAPTCHA required'], 403);
}
return $next($request);
}
Register in app/Http/Kernel.php:
'api' => [
\App\Http\Middleware\ValidateCaptcha::class,
],
Testing Mock CAPTCHA responses in tests:
// tests/TestCase.php
protected function getEnvironmentSetUp($app)
{
$app['config']->set('laracaptcha', [
'service' => 'mock',
'mock' => [
'verify' => true, // or false to simulate failures
],
]);
}
Lazy-Loading Defer CAPTCHA validation until the last step of a multi-step form to reduce server load.
Caching Cache CAPTCHA responses for non-sensitive operations (if the service supports it):
$response = cache()->remember("captcha_{$token}", 300, function () use ($token) {
return LaraCaptcha::verify($token);
});
Async Validation For APIs, validate CAPTCHA asynchronously using Laravel Queues:
dispatch(new ValidateCaptchaJob($token))->onQueue('captcha');
How can I help you explore Laravel packages today?