Google reCAPTCHA Integration
Protect your application's sensitive forms (login, registration, password reset, etc.) from automated abuse. The Rhapsody framework provides a seamless integration with Google reCAPTCHA v2 (Checkbox) through a Twig view injector and a corresponding validation rule.
Step 1: Environment Variables
Store your site and secret keys inside the application's .env file.
The framework reads these values via $_ENV.
RECAPTCHA_SITE_KEY="your_site_key_here"
RECAPTCHA_SECRET_KEY="your_secret_key_here"
Step 2: Frontend Rendering
The base controller (or a custom view composer) automatically binds the reCAPTCHA
script and widget markup to the captcha_form variable. You only need
to print this variable inside your Twig form.
|raw filter. Without it, the browser will display the
markup as plain text and the widget will not work.
<form action="/register" method="POST">
<!-- CSRF Protection – always include for POST forms -->
{{ csrf_field() }}
<label for="email">Email</label>
<input type="email" name="email" id="email" required>
<!-- The reCAPTCHA widget will be inserted here -->
{{ captcha_form|raw }}
<button type="submit">Register</button>
</form>
The rendered HTML includes:
- The Google API script (
https://www.google.com/recaptcha/api.js) loaded asynchronously. - A
divwith classg-recaptchaand your site key as adata-sitekeyattribute.
You can customise the widget by passing additional attributes (e.g., data-theme, data-size)
by extending the Recaptcha::render() method – see the source code in
Rhapsody\Core\Helpers\Recaptcha.
Step 3: Backend Validation Rule
The framework's validator includes a built‑in recaptcha rule.
When applied to the field named g-recaptcha-response, it verifies
the token with Google's API using your secret key.
public function store(Request $request)
{
$rules = [
'name' => 'required|alpha_num|min:3',
'email' => 'required|email|unique:User',
'password' => 'required|min:8|confirmed',
'g-recaptcha-response' => 'required|recaptcha'
];
if (! $this->validator->validate($request->post(), $rules)) {
// Redirect back with error messages (flashed to session)
return $this->redirectBackWithErrors($this->validator->getErrors());
}
// Registration logic – only reached if reCAPTCHA is valid
// ...
}
recaptcha rule automatically handles:
- Empty or missing token → validation fails.
- Invalid secret key or network errors → validation fails (logged as a warning).
- Valid token → passes, and you can safely proceed.
Manual Verification (Optional)
If you need to verify the token outside the validator (e.g., in an AJAX endpoint),
you can use the static Recaptcha::verify() helper directly:
use Rhapsody\Core\Helpers\Recaptcha;
$responseToken = $request->post('g-recaptcha-response');
$clientIp = $request->getClientIp();
if (Recaptcha::verify($responseToken, $clientIp)) {
// Token is valid
} else {
// Handle failure
}
The verify() method performs a POST request to Google's siteverify API
using PHP's stream context – no external HTTP client is required.
Troubleshooting
- Widget does not appear: Check that
RECAPTCHA_SITE_KEYis set in your.envand that the variable is printed with|raw. - Validation always fails: Ensure your secret key is correct and that the domain in your Google admin panel matches your application's domain (including subdomain and protocol).
- “Invalid input secret” error: The secret key may be mis‑typed or you may be using a different environment key than expected.
- Rate limiting or timeouts: Google’s API may occasionally be slow; the helper returns
falseon any network error. Consider logging these failures for monitoring.
Testing reCAPTCHA in Your Test Suite
During automated testing, you might want to bypass the reCAPTCHA check. The easiest
way is to mock the validation rule or the Recaptcha helper.
See the Testing Suite documentation for details on
using mock() to simulate a successful verification.