shanechrisbarker.co.uk

Laravel and Google ReCAPTCHA v2

Published On: Thursday 10th of January 2019 17:45:40

Adding a Google ReCAPTCHA to any forms on your website is a wise decision. Forms are fantastic targets for bots of all kinds. If your form can be filled in and submitted by a bot, I'll happily bet that it will happen or already has. A ReCAPTCHA makes this process much more difficult for a bot helps prevent yourself from receiving spammy submissions. In this tutorial, we'll integrate a Google ReCAPTCHA into a Laravel form and use Guzzle to verify it with Google

At the time of writing, Google currently offers 2 versions of the ReCAPTCHA API. Both have slightly different integration methods. I'll cover v2 in this tutorial and v3 in the future.

To get started with either integration, you'll need to sign up for a ReCAPTCHA account and create the ReCAPTCHA within it. Head over to the Google ReCAPTCHA site and create an account. Once done, you should be met with the below screen: Google ReCapctha Creation Form

With our account created, we'll now get our application ready. We'll need to create a couple of files:

  • A view to hold our form and ReCAPTCHA.
  • A controller to handle our form submission and validate the response from Google.
  • A route for our requests.

We'll also install the Guzzle library. Guzzle is used for making HTTP requests and our Controller will use this to make our request to Google. We'll install Guzzle via Composer in the next step.

Setting up the application

Open up a terminal and navigate to the root of your application. If you don't have Composer installed, you'll need to head over to the Composer site and follow the installation instructions.
Once done, run the following command in your terminal:

composer require guzzlehttp/guzzle
This will update your composer.json file and pull in the Guzzle library.

Next, let's create our controller. For this tutorial, we'll just call it our FormController.
In the terminal again, run the following command:

php artisan make:controller FormController
This will create our controller in the app/Http/Controllers directory.

Now we have our controller, we'll provide a route to it. Open up the routes/web.php directory and add the following routes to it:

Route::get('/form', 'FormController@index');
Route::post('/form', 'FormController@post')->name('form.send');
With that done, open up the previously created FormController and add the index() function to it as below:
public function index()
{
    return view('form');
}

Creating the Form

The next step is creating the view that our index() action returns. Inside of the resources/views create a file named form.blade.php.

This file will be where our form lives so go ahead and the following code to it:

{{Form::open(['route' => 'form.send', 'id' => 'contact-form'])}} {{Form::label('name', 'Please Enter Your Email:')}} {{Form::email('name', null, ['placeholder' => 'hello@me.com', 'required' => 'required'])}} {{Form::submit('submit')}} {{Form::close()}}
If you now navigate to the /form URL of your application, you should now see our form. Doesn't look amazing but styling the form is not in the scope of this tutorial.

Class Form Not Found

If you hit an error at this point related to the Form() class not being found, you'll need to install it via Composer. Simply run the following command in your terminal to add it to your composer.json file.
composer require laravelcollective/html

Signing up for a Google ReCAPTCHA v2

The v2 Google ReCapatcha is one you're bound to recognise and is very easy to implement. Head over to your newly created ReCaptcha account and select the options as per the below screenshot:

A v2 ReCAPTCHA example

In this screenshot, we can see:

  • The Label field - This is just for our reference
  • The type of ReCAPTCHA that we are creating. In this instance, a v2 Checkbox.
  • The domains list - This is the list of domains that this ReCAPTCHA will work for. For this demo, I'll set this to demo.local
Hit the 'Register' button to move onto the next step.

On the next screen, we are given the keys and code that we'll need to to add to our application.

Important!

Although the public part of your key will be visible to anyone who inspects the HTML of your application, it is extremely important that you do not share the secret key with anyone! I've blanked it out on the screenshot.

We'll be adding this into Laravels .env file, which should be ignored by any version control you may be using.

A v2 ReCAPTCHA example

Open up your .env file and add the following code to it:

RECAPTCHA_SECRET_KEY=your-secret-key
Obviously you'll need to replace your-secret-key with the secret key you just created.

Next, you'll need to copy the code snippets provided - add them to your view file (resources/views/form). 0 The script tags should be placed in the head of your html/view. Go ahead and add head tags if you don't already have them. Once done and the script is included and loading, add the ReCAPTCHA div to your form like below:



{{Form::open(['route' => 'form.send', 'id' => 'contact-form'])}}
    {{Form::label('name', 'Please Enter Your Email:')}}
    {{Form::email('name', null, ['placeholder' => 'hello@me.com', 'required' => 'required'])}}
    {{Form::submit('submit')}}
    
{{Form::close()}}

A refresh of the page should now show your ReCAPTCHA:

A v2 ReCAPTCHA example

At this point, your form is ready to post to the FormController so open it up and lets add the post() function that told our routes/web.php to send our request too.

Sending our ReCAPTCHA to Google for verification

Our post() function is going to return a RedirectResponse as once the ReCAPTCHA has been valiated, we'll redirect our user somewhere (back to the form in this case). For this to happen, we'll need to tell Laravel that we'd like to use it. The same applies with our Guzzle library. Go ahead and add this code to the top of your FormController

namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Http\RedirectResponse;
use GuzzleHttp\Client;

Then add the following function to it:

public function post(Request $request)
{   // instantiate an instance of our Guzzle Client
    $client = new Client();

    // get the values from the posted form
    $data       = $request->input();

    // create an array and add to it ReCAPTCHA public key\ from our form
    // and the secret key from our .env file
    $formParams = [];
    $formParams = [
        'form_params' => [
            'secret'    => env('RECAPTCHA_SECRET_KEY'),
            'response'  => $data['g-recaptcha-response']
        ]
    ];

    // make the request and store the $response
    $response = $client->request
    (
        'post', // the method we want to use
        'https://www.google.com/recaptcha/api/siteverify', // the url to call
        $formParams // our array from above
    );

    // get the response as a JSON object
    $response = json_decode($response->getBody()->getContents());

    // check if the response was a success
    if (true === $response->success)  {
        // it was! The ReCAPTCHA passed!
        return Redirect()->back()->withSuccess('Yay! It passed!');
    }

    // the ReCAPTCHA was not valid
    return Redirect()->back()->withErrors('Boo! No good!');
}
And that's that! Your Google ReCAPTCHA is ready to roll! If you want to check 100% that it is working, just dd() the response, which should look like this:
{#231 ▼
  +"success": true
  +"challenge_ts": "2019-01-11T19:26:20Z"
  +"hostname": "demo.local"
If you have any comments or feedback on this article, please do get in touch. I shall be adding Disquss to the site shortly so commenting will also be welcomed (just don't swear at me too much).