Looking to hire Laravel developers? Try LaraJobs

gkcaptcha-laravel maintained by gkcaptcha

Description
Laravel integration for gkCAPTCHA: middleware, validation rule, Blade directive, and service provider
Last update
2026/03/26 22:31 (dev-main)
License
Downloads
0

Comments
comments powered by Disqus

gkcaptcha-laravel

Laravel integration package for gkCAPTCHA. Provides a service provider, middleware, validation rule, Blade directive, and Facade for CAPTCHA protection with a single line of configuration.

Requirements

  • PHP 8.1+
  • Laravel 10 or 11
  • gkcaptcha/gkcaptcha-php ^1.0 (included as a dependency)

Installation

composer require gkcaptcha/gkcaptcha-laravel

The package auto-discovers via Laravel's package auto-discovery. No manual registration required.

Configuration

Publish the config file:

php artisan vendor:publish --tag=gkcaptcha-config

Add to .env:

GKCAPTCHA_SECRET_KEY=sk_live_your_secret_key
GKCAPTCHA_SITE_KEY=pk_live_your_site_key
GKCAPTCHA_API_URL=https://gkcaptcha.gatekeeper.sa
GKCAPTCHA_TIMEOUT=5
GKCAPTCHA_FAIL_CLOSED=false
GKCAPTCHA_WIDGET_URL=https://gkcaptcha.gatekeeper.sa/widget/gk-captcha.js

Environment Variables

Variable Default Description
GKCAPTCHA_SECRET_KEY (required) Server-side secret key for token verification
GKCAPTCHA_SITE_KEY (required) Public site key for the widget
GKCAPTCHA_API_URL https://gkcaptcha.gatekeeper.sa gkCAPTCHA API base URL
GKCAPTCHA_TIMEOUT 5.0 Request timeout in seconds
GKCAPTCHA_FAIL_CLOSED false Block requests on network error (fail-closed)
GKCAPTCHA_WIDGET_URL https://gkcaptcha.gatekeeper.sa/widget/gk-captcha.js Widget script URL

Blade Directive

Add the CAPTCHA widget to any Blade template:

<form method="POST" action="/contact">
    @csrf
    <input type="text" name="email" />

    @gkcaptcha('pk_live_your_site_key')

    <button type="submit">Submit</button>
</form>

If GKCAPTCHA_SITE_KEY is set in .env, you can omit the argument:

@gkcaptcha

The directive outputs:

<gk-captcha sitekey="pk_live_your_site_key"></gk-captcha>
<script src="https://gkcaptcha.gatekeeper.sa/widget/gk-captcha.js" defer></script>

Middleware

Route Group (recommended)

Protect a group of routes by adding VerifyCaptcha to a route group:

use GkCaptcha\Laravel\Http\Middleware\VerifyCaptcha;

Route::middleware([VerifyCaptcha::class])->group(function () {
    Route::post('/contact', [ContactController::class, 'store']);
    Route::post('/register', [RegisterController::class, 'store']);
});

Global Kernel Registration (Laravel 10)

In app/Http/Kernel.php:

protected $routeMiddleware = [
    // ...
    'captcha' => \GkCaptcha\Laravel\Http\Middleware\VerifyCaptcha::class,
];

Then use the alias:

Route::post('/contact', [ContactController::class, 'store'])->middleware('captcha');

Token Sources

The middleware reads the CAPTCHA token from (in priority order):

  1. captchaToken body field (form POST or JSON body)
  2. X-Captcha-Token request header (AJAX / API)

Middleware Responses

Condition HTTP Status Body
No token present 403 {"success": false, "error": "CAPTCHA token required"}
Token invalid 403 {"success": false, "error": "CAPTCHA verification failed"}
Network error (fail-open) passes through Warning logged, request continues
Token valid passes through Normal route response

Validation Rule

Use the gkcaptcha rule in form request classes or inline validators:

// In a FormRequest class:
public function rules(): array
{
    return [
        'email'        => 'required|email',
        'captchaToken' => 'required|gkcaptcha',
    ];
}

Or with the Rule object directly:

use GkCaptcha\Laravel\Rules\GkCaptchaRule;
use GkCaptcha\GkCaptchaClient;

$rules = [
    'captchaToken' => ['required', new GkCaptchaRule(app(GkCaptchaClient::class))],
];

$validator = Validator::make($request->all(), $rules);

Facade

For inline verification anywhere in your application:

use GkCaptcha\Laravel\Facades\GkCaptcha;

$result = GkCaptcha::verifyToken(
    token:     $request->input('captchaToken'),
    clientIP:  $request->ip(),
    userAgent: $request->userAgent(),
);

if (!$result->success) {
    abort(403, 'CAPTCHA verification failed');
}

Fail-Open Behavior

By default (GKCAPTCHA_FAIL_CLOSED=false), network errors when reaching the gkCAPTCHA API allow the request to proceed. A warning is logged:

[warning] gkCAPTCHA API unreachable, failing open {"error": "..."}

This prevents gkCAPTCHA API availability from causing downtime on your application.

Set GKCAPTCHA_FAIL_CLOSED=true to block requests when the API is unreachable. This is appropriate for high-security environments where it is better to reject users than to risk allowing bots through.

Testing

The package includes PHPUnit-compatible tests using Orchestra Testbench.

With dependencies installed:

cd sdks/laravel
composer install
./vendor/bin/phpunit tests/

For environments without Composer (CI, Docker images without Testbench), a standalone runner is included:

php tests/run_tests.php

License

MIT