Paulund
2018-04-03 #laravel

How To Add Google reCAPTCHA To Laravel

In this tutorial we're going to learn how we can add Google reCAPTCHA to your forms in Laravel.

For this functionality we're going to use the free Google service reCAPTCHA, this service helps guard against spam bots from submitting your form with invalid spam data.

reCAPTCHA

First you need to sign up to the reCAPTCHA service and register your site for one of the three types V2, invisible or Android.

This will generate two keys you'll need to use on your site. The site key and the secret key.

Environment File

Take these keys and add them to your .env file.

RECAPTCHA_SITE_KEY=njdgfd87gf7dgfdgufd6f7g6fd78g6df7g6fdgfdgfdgergdfgfd
RECAPTCHA_SECRET_KEY=we23uykui89erewdsvscxJSDGBFJDNANnkjnkd984

Client Form

The first thing you need to do with your form is to add the Google JavaScript file just before the closing </head> tag.

<script src='https://www.google.com/recaptcha/api.js'></script>
<script>
function onSubmit(token) {
    document.getElementById("register-form").submit();
}
</script>

Next you need to replace your form submit button with the following code.

<button
class="g-recaptcha"
data-sitekey="njdgfd87gf7dgfdgufd6f7g6fd78g6df7g6fdgfdgfdgergdfgfd"
data-callback="onSubmit">
Submit
</button>

This will add your site key to the button and will add a JavaScript callback function which will run on the click event of the button.

With the form setup we can create the server side functionality to validate the form request.

Server Side Integration

When the form is submitted you'll have a $_POST value of g-recaptcha-response we can use this value to verify the request on the Google side. To valid the request we're going to create a Laravel custom form validation class.

To create a new Laravel validation rule use the following command.

php artisan make:rule GoogleRecaptcha

This will create a new file in App\Rules\GoogleRecaptcha.php with two functions passes and message.

The passes function is used to house the code to verify the the POST request. The message function is used to return the error message.

The passes function needs to make a call to the the endpoint https://www.google.com/recaptcha/api/siteverify with the secret key and the response from the form.

Below is the complete class you can use to validate the request.

<?php

namespace App\Rules;

use GuzzleHttp\Client;
use Illuminate\Contracts\Validation\Rule;

class GoogleRecaptcha implements Rule
{
    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        $client = new Client();
        $response = $client->post('https://www.google.com/recaptcha/api/siteverify',
            [
                'form_params' => [
                    'secret' => env('RECAPTCHA_SECRET_KEY', false),
                    'remoteip' => request()->getClientIp(),
                    'response' => $value
                ]
            ]
        );
        $body = json_decode((string)$response->getBody());
        return $body->success;
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return 'Are you a robot?';
    }
}

If the Google reCaptcha returns successful the validation class will pass, if there is a failure is verifying the request then the validation rule will fail.

Use The Validation Rule

With the validation rule created we can now use this when validating the requests.

/**
 * Get a validator for an incoming registration request.
 *
 * @param  array  $data
 * @return \Illuminate\Contracts\Validation\Validator
 */
protected function validator(array $data)
{
    return Validator::make($data, [
        'name' => 'required|string|max:255',
        'email' => 'required|string|email|max:255|unique:users',
        'password' => 'required|string|min:6|confirmed',
        'g-recaptcha-response' => ['required', new GoogleRecaptcha]
    ]);
}

That it now your form requests can be verified by using the reCAPTCHA service.