Hace ya bastante meses hice un artículo sobre como integrar Google reCAPTCHA en Laravel 5.8 pero ya es hora de darle un refresh a ese artículo con las nuevas versiones tanto de Laravel como de las librerías que podemos integrar para agregarle seguridad a nuestros formularios.

Requerimientos

Antes de hacer cualquier cosa, es necesario verificar que tengamos alguna de estas versiones de Laravel:

  • 5.5 o mayor
  • 6
  • 7
  • 8

Lo recomendable es tener alguna de estas versiones, en dado caso que no puedas migrar a una de las anteriores, al final te dejaré la documentación oficial que te puede guiar en tu versión de Laravel.

Instalación

Para integrar reCAPTCHA en nuestro proyecto, es necesario instalar una librería de terceros, lo podemos realizar ejecutando el siguiente comando:

composer require biscolab/laravel-recaptcha

Por defecto Laravel descubre en automático los paquetes que instalas con Composer pero puede existir la probabilidad que en tu proyecto desactivaste esta opción, si es así, será necesario que agregues el provider en tu archivo config/app.php.

'providers' => [
    ...
    Biscolab\ReCaptcha\ReCaptchaServiceProvider::class,
];

Si lo deseas, puedes agregar un Facade para abreviar el nombre de las clases de la librería:

'aliases' => [
    ...
    'ReCaptcha' => Biscolab\ReCaptcha\Facades\ReCaptcha::class,
];

Configuración

Una vez que hayas pasado el proceso de instalación, necesitaremos configurar lo necesario para que el paquete funcione en nuestro proyecto Laravel.

Publicación de paquete

Necesitarás publicar los archivos de configuración que ofrece el paquete, lo puedes hacer ejecutando el siguiente comando:

php artisan vendor:publish --provider="Biscolab\ReCaptcha\ReCaptchaServiceProvider"

Esto creará un archivo llamado recaptcha.php en tu carpeta de configuración, el cual contendrá algo como lo siguiente:

return [
    'api_site_key'                  => env('RECAPTCHA_SITE_KEY', ''),
    'api_secret_key'                => env('RECAPTCHA_SECRET_KEY', ''),
    // changed in v4.0.0
    'version'                       => 'v2', // supported: "v3"|"v2"|"invisible"
    // @since v3.4.3 changed in v4.0.0
    'curl_timeout'                  => 10,
    'skip_ip'                       => [], // array of IP addresses - String: dotted quad format e.g.: "127.0.0.1"
    // @since v3.2.0 changed in v4.0.0
    'default_validation_route'      => 'biscolab-recaptcha/validate',
    // @since v3.2.0 changed in v4.0.0
    'default_token_parameter_name' => 'token',
    // @since v3.6.0 changed in v4.0.0
    'default_language'             => null,
    // @since v4.0.0
    'default_form_id'              => 'biscolab-recaptcha-invisible-form', // Only for "invisible" reCAPTCHA
    // @since v4.0.0
    'explicit'                     => false, // true|false
    // @since v4.3.0
    'api_domain'                   => "www.google.com", // default value is "www.google.com"
    // @since v4.0.0
    'tag_attributes'               => [
        'theme'                    => 'light', // "light"|"dark"
        'size'                     => 'normal', // "normal"|"compact"
        'tabindex'                 => 0,
        'callback'                 => null, // DO NOT SET "biscolabOnloadCallback"
        'expired-callback'         => null, // DO NOT SET "biscolabOnloadCallback"
        'error-callback'           => null, // DO NOT SET "biscolabOnloadCallback"
    ]
];

En el código anterior podemos ver en la línea 2 y 3 nos solicita 2 variables de entorno:

  • RECAPTCHA_SITE_KEY (clave pública)
  • RECAPTCHA_SECRET_KEY (clave privada)

Estas credenciales las puedes generar en la consola de Google reCAPTCHA, puedes visitarlo a continuación: https://www.google.com/recaptcha/admin/

Variables de entorno

Las variables de entorno que solicita el paquete no existen actualmente en tu proyecto, es por eso que tenemos que dirigirnos a tu archivo .env que está ubicado en la raíz de tu proyecto y agregar al final de tu archivo lo siguiente:

RECAPTCHA_SITE_KEY=TU_CLAVE_PUBLICA
RECAPTCHA_SECRET_KEY=TU_CLAVE_PRIVADA

Con esto tendríamos integrando y funcionando la versión 2 de Google reCAPTCHA, solamente que tenemos que verificar que Laravel tome nuestra configuración ejecutando el siguiente comando:

php artisan config:clear

De esta manera Laravel va a purgar toda la configuración y va a refrescar el caché almacenado.

Implementación

Después que instalamos y configuramos el paquete, tenemos que integrar los scripts necesarios para poder renderizar Google reCAPTCHA.

Agregar scripts y estilos

En tu HTML tendrás que agregar la directiva de la librería antes de cerrar <head>, de tal forma que quede algo similar a:

<!DOCTYPE html>
<html>
    <head>
        ...
        {!! htmlScriptTagJsApi(['lang' => 'es']) !!}
    </head>

Integración en formulario

Dentro de la etiqueta <form> del formulario que quieres proteger con Google reCAPTCHA, tendrás que agregar el helper htmlFormSnippet() que provee la librería, quedando algo similar a lo siguiente:

<form>
    @csrf
    ...
    {!! htmlFormSnippet() !!}

    <input type="submit">
</form>

Configuración personalizada

Si tu proyecto lo requiere, puedes mandar parametros personalizados al helper anterior, de forma en que quede:

{!! htmlFormSnippet([
    "theme" => "light",
    "size" => "normal",
    "tabindex" => "3",
    "callback" => "callbackFunction",
    "expired-callback" => "expiredCallbackFunction",
    "error-callback" => "errorCallbackFunction",
]) !!}

Puedes leer la documentación oficial en: https://laravel-recaptcha-docs.biscolab.com/docs/how-to-use-v2#recaptcha-v2-checkbox

Hasta ahora hemos integrando solamente Google reCAPTCHA en el frontend, pero necesitamos agregar un proceso de validación.

Validación en el controlador

Puedes tener algo como lo siguiente en caso de que valides todo en la parte del controlador (no recomendable)

$validator = Validator::make(request()->all(), [
    ...
    'g-recaptcha-response' => 'recaptcha',
]);

// Verificamos si hay algún error
if($validator->fails()) {
    ...
    $errors = $validator->errors();
}

O si prefieres dividir la lógica en un request personalizado (sería lo más prudente), puedes tener algo similar a lo siguiente:

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class FormExampleRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'g-recaptcha-response' => 'recaptcha',
        ];
    }
}

De esa forma mantienes un código mucho más limpio y ordenado.

Y de esa forma quedará integrado en su totalidad Google reCAPTCHA en tu proyecto, lo puedes replicar todas las veces que requieras, no tengas ningún problema.

Si te ha servido este artículo, te agradecería mucho si puedes compartirlo en redes sociales o a algún conocido que pueda servirle el artículo, me ayudarás demasiado en seguir trayendo contenido de calidad al blog.