Integrando "Invisible reCAPTCHA" de Google de forma fácil en Laravel
Este artículo tiene más de un año de antigüedad, el contenido pudiera estar obsoleto.
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 según sus necesidades).
Esta clase va a contener lo siguiente:
1<?php 2namespace App\Helpers; 3 4use GuzzleHttp\Client; 5 6/** 7 * ReCaptcha 8 */ 9class ReCaptcha10{11 const CAPTCHA_URL = 'https://www.google.com/recaptcha/api/';12 const TIMEOUT = 20.0;13 14 protected $client;15 16 public function __construct()17 {18 $this->client = new Client([19 'base_uri' => self::CAPTCHA_URL,20 'timeout' => self::TIMEOUT,21 ]);22 }23 24 /**25 * validateCaptcha26 *27 * @param [type] $recaptcha28 * @return void29 */30 public function validateCaptcha($recaptcha)31 {32 $captchaData = [33 'headers' => [34 'content-type' => 'application/x-www-form-urlencoded',35 'accept' => 'application/json',36 'cache-control' => 'no-cache'37 ],38 'form_params' => [39 'secret' => config('google.recaptcha_secret_key'),40 'response' => $recaptcha41 ]42 ];43 44 $request = $this->client->request('POST', 'siteverify', $captchaData);45 $body = $request->getBody()->getContents();46 $response = json_decode($body, true);47 // score over 0.5 human48 return $response['score'] >= '0.5' ? true : false;49 }50}
Luego en nuestro AppServiceProvider
en el método register
colocamos esto
1$this->app->bind(ReCaptcha::class, function () {2 return new ReCaptcha;3});
Y en el método boot
colocamos lo siguiente:
1Blade::directive('rederRecaptchaJs', function ($key, $action = 'contact_form' ) { 2 return ' 3 <script src="https://www.google.com/recaptcha/api.js?render='.$key.'"></script> 4 <script>grecaptcha.ready(function() {grecaptcha.execute("'.$key.'", {action: "'.$action.'"}).then(function(token) {if (token) { document.getElementById("recaptcha").value = token }});});</script>'; 5}); 6 7Blade::directive('rederRecaptcha', function ($key) { 8 return '<input type="hidden" name="recaptcha" id="recaptcha"> 9 <div class="recaptcha_text_render"> This site is protected by reCAPTCHA and the Google10 <a class="recaptcha_text_link_render" href="https://policies.google.com/privacy" target="_blank">Privacy Policy</a> and11 <a class="recaptcha_text_link_render" href="https://policies.google.com/terms" target="_blank">Terms of Service</a> apply.12 </div>';13});
Para usarlo en las vistas como una directiva normal de blade, en este caso sería:
1@rederRecaptchaJs()2@rederRecaptcha
Y ya, para finalizar hacemos lo siguiente en el controlador donde se necesite usar este recaptcha:
1public $recaptcha; 2 3public function __construct(ReCaptcha $recaptcha) 4{ 5 $this->recaptcha = $recaptcha; 6} 7 8/** 9 * Handle the incoming request.10 *11 * @param \Illuminate\Http\Request $request12 * @return \Illuminate\Http\Response13 */14public function __invoke(ContactFormRequest $request)15{16 if ($this->recaptcha->validateCaptcha($request->recaptcha)) {17 //18 }19 //20}
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.