ikeda / php-captcha-for-recaptcha-v3
Google reCAPTCHA v3 for PHP scripts
1.1.1
2025-08-12 10:34 UTC
Requires
- php: >=8.3
- google/recaptcha: ^1.3
Requires (Dev)
- phpunit/phpunit: ^12.3
- roave/security-advisories: dev-latest
README
Use Google reCAPTCHA (v3) to protect your sites from fraudulent activities, spam, and abuse.
Usage
for Laravel 12.x app
config/captcha.php
<?php return [ 'site_key' => 'SITE_KEY', 'secret' => 'SECRET', ];
app/Providers/AppServiceProvider.php
<?php namespace App\Providers; use Illuminate\Foundation\Application; use Illuminate\Contracts\Support\Htmlable; use Illuminate\Support\HtmlString; use Illuminate\Support\ServiceProvider; use PiCaptcha\Captcha; class AppServiceProvider extends ServiceProvider { public function register(): void { $this->app->singleton(Captcha::class, static fn (Application $app): Captcha => new Captcha($app['config']['captcha']['secret'])); } public function boot(): void { Blade::directive('captchaScript', static fn (string $expression): Htmlable => new HtmlString(Captcha::js($expression))); } }
resources/views/layouts/sample.blade.php
<!DOCTYPE html> <html lang="{{ str_replace('_', '-', app()->getLocale()) }}"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="csrf-token" content="{{ csrf_token() }}"> <title>{{ config('app.name', 'Laravel') }}</title> @captchaScript(config('captcha.site_key')) @vite(['resources/css/app.css', 'resources/js/app.js']) @stack('head') </head> <body> <div> {{ $slot }} </div> </body> </html>
app/Http/Controllers/Captcha/VerifyTokenController.php
<?php namespace App\Http\Controllers\Captcha; use PiCaptcha\Captcha; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; class VerifyTokenController { private Captcha $captcha; public function __construct(Captcha $captcha) { $this->captcha = $captcha; } public function __invoke(Request $request): JsonResponse { $action = $request->input('action'); $token = $request->input('token'); $hostname = $request->getHost(); $clientIp = $request->getClientIp(); $result = $this->captcha->verify(token: $token, clientIp: $clientIp, action: $action, score: 0.1, hostname: $hostname) return new JsonResponse((object) ['success' => $result->isSuccess()]); } }
routes/web.php
<? use Illuminate\Support\Facades\Route; Route::get('/captcha/verify', App\Http\Controllers\Captcha\VerifyTokenController::class)->name('captcha.verify');
(Client Side)
resources/views/captcha/sample.blade.php
<x-sample-layout> <script> grecaptcha.ready(() => { grecaptcha.execute(`{{ config('captcha.site_key') }}`, { action: 'examples/recaptcha' }).then((token) => { fetch(`{{ route('captcha.verify') }}?action=examples/recaptcha&token=${token}`).then((response) => { response.json().then((data) => { if (data.success) { // Add your logic to submit to your backend server here. } }); }); }); }); </script> <div> <from> <!-- ... --> </form> </div> </x-sample-layout>
(for Backend Server)
resources/views/captcha/sample.blade.php
<x-sample-layout> <div> <from> <input type="hidden" name="captcha_token" id="input-captcha-token"> <!-- ... --> </form> </div> <script> grecaptcha.ready(() => { grecaptcha.execute(`{{ config('captcha.site_key') }}`, { action: 'examples/recaptcha' }).then((token) => { const input = document.getElementById('input-captcha-token'); input.value = token; }); }); </script> </x-sample-layout>