anhskohbo/no-captcha
Laravel package to integrate Google reCAPTCHA “No CAPTCHA” into your app. Provides helpers to render the JS, display normal or invisible widgets, and validate responses. Supports Laravel auto-discovery, with simple .env configuration for site key and secret.
composer require anhskohbo/no-captcha
.env:
NOCAPTCHA_SECRET=your_secret_key
NOCAPTCHA_SITEKEY=your_site_key
For Laravel 5.5+, auto-discovery handles the rest. For older versions, register the service provider and facade alias in config/app.php.{!! NoCaptcha::renderJs() !!}
{!! NoCaptcha::display() !!}
$validator = Validator::make(request()->all(), [
'g-recaptcha-response' => 'required|captcha',
]);
Frontend Integration:
{!! NoCaptcha::renderJs('en', false, 'recaptchaCallback') !!}
<form method="POST" action="/submit">
<!-- Form fields -->
{!! NoCaptcha::display(['data-theme' => 'dark']) !!}
<button type="submit">Submit</button>
</form>
{!! NoCaptcha::displaySubmit('form-id', 'Submit', ['data-theme' => 'dark']) !!}
Backend Validation:
public function store(StoreFormRequest $request) {
// Validation handled by FormRequest
}
In StoreFormRequest.php:
public function rules() {
return [
'g-recaptcha-response' => 'required|captcha',
];
}
resources/lang/en/validation.php:
'custom' => [
'g-recaptcha-response' => [
'required' => 'Please verify you are not a robot.',
'captcha' => 'CAPTCHA verification failed. Please try again.',
],
],
API Protection:
// app/Http/Middleware/ValidateRecaptcha.php
public function handle($request, Closure $next) {
if ($request->is('api/*') && !$request->has('g-recaptcha-response')) {
return response()->json(['error' => 'CAPTCHA required'], 403);
}
if ($request->has('g-recaptcha-response') && !NoCaptcha::verifyResponse($request->input('g-recaptcha-response'))) {
return response()->json(['error' => 'Invalid CAPTCHA'], 403);
}
return $next($request);
}
app/Http/Kernel.php:
protected $routeMiddleware = [
'recaptcha' => \App\Http\Middleware\ValidateRecaptcha::class,
];
Route::post('/api/submit', [Controller::class, 'store'])->middleware('recaptcha');
Per-Form Enforcement: Disable reCAPTCHA for low-risk forms by omitting validation or using conditional logic:
$rules = [];
if ($this->isHighRiskForm()) {
$rules['g-recaptcha-response'] = 'required|captcha';
}
Language Support: Localize reCAPTCHA for multilingual apps:
{!! NoCaptcha::renderJs(app()->getLocale()) !!}
NoCaptcha::shouldReceive('verifyResponse')
->once()
->andReturn(true);
$response = $this->post('/submit', [
'g-recaptcha-response' => 'test-token',
'name' => 'Test User',
]);
$response = $this->post('/submit', ['name' => 'Test User']);
$response->assertSessionHasErrors('g-recaptcha-response');
Missing JavaScript:
NoCaptcha::renderJs() is omitted, the reCAPTCHA widget won’t render.Token Validation Timing:
displaySubmit) requires the form ID to auto-submit on success. If the form ID is incorrect or missing, the callback fails silently.displaySubmit():
{!! NoCaptcha::displaySubmit('my-form-id', 'Submit') !!}
<form id="my-form-id" method="POST">
Rate Limiting:
Testing Quirks:
NoCaptcha::display() in tests returns a hidden input, which may bypass frontend validation.NoCaptcha::shouldReceive('verifyResponse')->andReturn(true);
$response = $this->post('/submit', ['g-recaptcha-response' => '1']);
Laravel Version Mismatches:
v1 for Laravel 4).NOCAPTCHA_SECRET and NOCAPTCHA_SITEKEY.https://www.google.com/recaptcha/api/siteverify) succeeds in browser dev tools or Laravel logs.NOCAPTCHA_DEBUG=true to .env to log API responses (if supported in future versions).Custom Validation Logic:
use Anhskohbo\NoCaptcha\Rules\Recaptcha;
$rules = [
'g-recaptcha-response' => [new Recaptcha(), 'required'],
];
Fallback Mechanisms:
if (!NoCaptcha::verifyResponse($token)) {
// Fallback: Use a simple CAPTCHA or block the request
return response()->json(['error' => 'Service unavailable'], 503);
}
Invisible reCAPTCHA (v3) Integration:
displaySubmit for v3 or manually integrate v3’s scoring API:
$response = NoCaptcha::verifyResponse($token, 'v3');
$score = $response['score']; // Use score for risk-based decisions
Middleware for API Routes:
public function handle($request, Closure $next) {
if (!$request->hasValidRecaptcha()) { // Custom method
return response()->json(['error' => 'Invalid CAPTCHA'], 403);
}
return $next($request);
}
NOCAPTCHA_SECRET and NOCAPTCHA_SITEKEY are set in .env and cached (run php artisan config:cache if using caching).display() method accepts HTML attributes (e.g., data-theme, data-size). Refer to Google’s docsHow can I help you explore Laravel packages today?