nguyentranchung/laravel-google-recaptcha
Installation:
composer require nguyentranchung/laravel-google-recaptcha
Publish the config file:
php artisan vendor:publish --provider="NguyenTrungChung\LaravelGoogleRecaptcha\LaravelGoogleRecaptchaServiceProvider"
Configuration:
Edit .env with your Google reCAPTCHA keys:
RECAPTCHA_SITE_KEY=your_site_key_here
RECAPTCHA_SECRET_KEY=your_secret_key_here
RECAPTCHA_VERSION=v2 # or v3
First Use Case:
Add validation to a form (e.g., ContactFormRequest):
use NguyenTrungChung\LaravelGoogleRecaptcha\Rules\Recaptcha;
public function rules()
{
return [
'g-recaptcha-response' => ['required', new Recaptcha],
];
}
Frontend Integration: Include the reCAPTCHA script in your Blade view:
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
Add the reCAPTCHA widget to your form:
<div class="g-recaptcha" data-sitekey="{{ config('recaptcha.site_key') }}"></div>
Form Validation:
Use the Recaptcha rule in Form Requests or manually in controllers:
$validator = Validator::make($request->all(), [
'g-recaptcha-response' => ['required', new Recaptcha],
]);
Dynamic Site Key: Pass the site key dynamically to Blade views:
// In a controller
return view('form', ['siteKey' => config('recaptcha.site_key')]);
<!-- In Blade -->
<div class="g-recaptcha" data-sitekey="{{ $siteKey }}"></div>
API Endpoints: For API-based forms, include the token in the request body:
$validator = Validator::make($request->all(), [
'recaptcha_token' => ['required', new Recaptcha],
]);
Conditional Validation: Skip reCAPTCHA for trusted users (e.g., logged-in admins):
$rules = ['g-recaptcha-response' => new Recaptcha];
if (auth()->check() && auth()->user()->isAdmin()) {
unset($rules['g-recaptcha-response']);
}
Custom Error Messages: Override default validation messages:
$validator = Validator::make($request->all(), [
'g-recaptcha-response' => ['required', new Recaptcha],
], [
'g-recaptcha-response.required' => 'Please complete the CAPTCHA.',
'g-recaptcha-response.recaptcha' => 'Invalid CAPTCHA. Please try again.',
]);
Laravel Fortify/Passport: Extend authentication requests with reCAPTCHA:
public function rules()
{
return array_merge(parent::rules(), [
'g-recaptcha-response' => ['required', new Recaptcha],
]);
}
Laravel Nova: Add reCAPTCHA to custom Nova actions or resource tools by extending the validation logic in the underlying controller.
Queueable Jobs: Validate reCAPTCHA in a job before processing (e.g., newsletter subscriptions):
public function handle()
{
$validator = Validator::make(['token' => $this->token], [
'token' => ['required', new Recaptcha],
]);
if ($validator->fails()) {
throw new \Exception('Invalid CAPTCHA');
}
// Proceed with job
}
Testing:
Use the Recaptcha::fake() method in tests to bypass validation:
public function test_form_submission()
{
Recaptcha::fake();
$response = $this->post('/contact', ['name' => 'Test']);
$response->assertRedirect('/thank-you');
}
Deprecated Package:
bestmomo/laravel-recaptcha for v3 support.Recaptcha rule to support v3.Config File Issues:
.env structure. Ensure:
// config/recaptcha.php
'site_key' => env('RECAPTCHA_SITE_KEY'),
'secret_key' => env('RECAPTCHA_SECRET_KEY'),
'version' => env('RECAPTCHA_VERSION', 'v2'),
php artisan config:clear
Frontend Script Loading:
async defer) to avoid blocking page rendering. Place it just before </body>:
<body>
<!-- Your content -->
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
</body>
Token Expiry:
Local Development:
ngrok to expose your site via HTTPS or mock the validation in tests (as shown above).Validation Failures:
$validator = Validator::make([...], [...]);
if ($validator->fails()) {
\Log::error('reCAPTCHA Error:', $validator->errors()->toArray());
}
invalid-domain-association: Ensure your domain is listed in the Google reCAPTCHA admin panel.timeout-or-duplicate: Token expired or already used.Network Requests:
https://www.google.com/recaptcha/api/siteverify. Verify the secret and response parameters are correct.Testing Locally:
Recaptcha::fake() method to bypass validation during development:
Recaptcha::fake(); // Add to a test or middleware
Custom Validation Logic:
Extend the Recaptcha rule to add custom logic (e.g., score thresholds for v3):
use NguyenTrungChung\LaravelGoogleRecaptcha\Rules\Recaptcha as BaseRecaptcha;
class CustomRecaptcha extends BaseRecaptcha
{
public function __construct($version = 'v3', $minScore = 0.9)
{
parent::__construct($version);
$this->minScore = $minScore;
}
public function passes($attribute, $value)
{
if ($this->version === 'v3') {
$response = $this->verify($value);
return $response['success'] && $response['score'] >= $this->minScore;
}
return parent::passes($attribute, $value);
}
}
Middleware for API: Create middleware to validate reCAPTCHA on API routes:
namespace App\Http\Middleware;
use Closure;
use NguyenTrungChung\LaravelGoogleRecaptcha\Rules\Recaptcha;
class ValidateRecaptcha
{
public function handle($request, Closure $next)
{
$validator = \Validator::make($request->all(), [
'recaptcha_token' => ['required', new Recaptcha],
]);
if ($validator->fails()) {
return response()->json(['error' => 'Invalid CAPTCHA'], 422);
}
return $next($request);
}
}
Register in app/Http/Kernel.php:
protected $routeMiddleware = [
'recaptcha' => \App\Http\Middleware\ValidateRecaptcha::class,
];
Use in routes:
Route::post('/api/contact', function () { ... })->middleware('recaptcha');
Event Listeners: Trigger events on successful/failed validation (e.g., log attempts):
// In a service provider
$validator
How can I help you explore Laravel packages today?