Vamos a integrar "Invisible reCAPTCHA" de Google en Laravel en menos de 5 minutos.
Ok, lo primero que hay que hacer es crear las llaves que vamos a usar para ello debemos is a: https://www.google.com/recaptcha/admin/create recuerden que debemos seleccionar reCAPTCHA v3
Bien, ya tenemos las llaves ahora necesitamos hacer es crear una clase que podemos llamar CustomGoogleRecaptcha
y tendrá el siguiente namespace App\Helpers
(pueden adaptarlo segun sus necesidades).
Esta clase va a contener lo siguiente:
<?php
namespace App\Helpers;
use GuzzleHttp\Client;
/**
* ReCaptcha
*/
class ReCaptcha
{
const CAPTCHA_URL = 'https://www.google.com/recaptcha/api/';
const TIMEOUT = 20.0;
protected $client;
public function __construct()
{
$this->client = new Client([
'base_uri' => self::CAPTCHA_URL,
'timeout' => self::TIMEOUT,
]);
}
/**
* validateCaptcha
*
* @param [type] $recaptcha
* @return void
*/
public function validateCaptcha($recaptcha)
{
$captchaData = [
'headers' => [
'content-type' => 'application/x-www-form-urlencoded',
'accept' => 'application/json',
'cache-control' => 'no-cache'
],
'form_params' => [
'secret' => config('google.recaptcha_secret_key'),
'response' => $recaptcha
]
];
$request = $this->client->request('POST', 'siteverify', $captchaData);
$body = $request->getBody()->getContents();
$response = json_decode($body, true);
// score over 0.5 human
return $response['score'] >= '0.5' ? true : false;
}
}
Luego en nuestro AppServiceProvider
en el método register
colocamos esto
$this->app->bind(ReCaptcha::class, function () {
return new ReCaptcha;
});
Y en el método boot
colocamos lo siguiente:
Blade::directive('rederRecaptchaJs', function ($key, $action = 'contact_form' ) {
return '
<script src="https://www.google.com/recaptcha/api.js?render='.$key.'"></script>
<script>grecaptcha.ready(function() {grecaptcha.execute("'.$key.'", {action: "'.$action.'"}).then(function(token) {if (token) { document.getElementById("recaptcha").value = token }});});</script>';
});
Blade::directive('rederRecaptcha', function ($key) {
return '<input type="hidden" name="recaptcha" id="recaptcha">
<div class="recaptcha_text_render"> This site is protected by reCAPTCHA and the Google
<a class="recaptcha_text_link_render" href="https://policies.google.com/privacy" target="_blank">Privacy Policy</a> and
<a class="recaptcha_text_link_render" href="https://policies.google.com/terms" target="_blank">Terms of Service</a> apply.
</div>';
});
Para usarlo en las vistas como una directiva normal de blade, en este caso sería:
@rederRecaptchaJs()
@rederRecaptcha
Y ya, para finalizar hacemos lo siguiente en el controlador donde se necesite usar este recaptcha:
public $recaptcha;
public function __construct(ReCaptcha $recaptcha)
{
$this->recaptcha = $recaptcha;
}
/**
* Handle the incoming request.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function __invoke(ContactFormRequest $request)
{
if ($this->recaptcha->validateCaptcha($request->recaptcha)) {
//
}
//
}
Acá la validación que se hace es el score del usuario, donde un valor menor a 0.5 es considerado un bot.
Espero que les sirva.