Add Google reCaptcha v3 on Laravel App

October 20, 2019

reCAPTCHA is awesome tool, especially v3 version, to clean your app from bots.

Main benefit of third generation of reCaptcha tool in comparison with older versions is that this tool now works fully invisible for end users. And gives more variety to control and analyze traffic on website.

Sounds good, is it? Especially when end user will not be required to select this boring pics anymore.

Main purposes to add this into your site

Main purposes to implement reCaptcha v3 into your website is:

  • To secure website from bots
  • For E-commerce, to not loose potential buyer while it is trying to select annoying images on reCaptcha’s older version (v2)
  • To get more website trafic information.
  • To verify posts comments before publish.

How to implement reCaptcha in Laravel app

To implement this tool into our Laravel app I will split tutorial into 3 easy steps: New site registration in Google reCaptcha Admin panel, Front-End setup and finally Backend setup.

Register new site

First of all we need add your site into Google reCaptcha admin panel and get api keys for future work. To do so, please go to recaptcha admin panel, here is link, There on right top corner press on button ‘Admin console’.

If you are no logged into google account, do it, or create new google account. After that you will be redirected in reCaptcha admin panel.

There in right top corner press on plus sign ‘+’.

In newly opened site registration form fill all necessary data:

  • Label is your new site name in reCaptcha system.
  • Select recpatcha version. In our case it is v3.
  • Provide domain of your website. If you want to get key for development and do not have valid domain, then you can fill domain field with localhost value.

Accept terms of use and submit data.

After that you should see two keys generated for your site. One is the SITE_KEY which is used in the front-end and the other is the SECRET_KEY for usage in backend. Later this data can be found in site’s settings page.

Setup in Front-End

Front-End setup is pretty easy. But first to be correct, lets add our keys into .env file.

Open .env file which is in root of laravels project and add keys:

G_RECAPTCHA_SITE_KEY="please add your site key here"
G_RECAPTCHA_SECRET_KEY="please add your secret key here"

When your keys now are located in .env file we can select form on site in which you want to use reCaptcha. In our case this will be basic Laravel login form which is located here: /resources/views/auth/login.blade.php .

And add there in bottom of page recaptcha’s script. Example:

<script src="https://www.google.com/recaptcha/api.js?render={{env('G_RECAPTCHA_SITE_KEY')}}"></script>
<script>
    grecaptcha.ready(function() {
        grecaptcha.execute("{{env('G_RECAPTCHA_SITE_KEY')}}", {action: 'homepage'}).then(function(token) {
            if(token) {
                //js
                document.getElementById('recaptcha_v3').value = token;
                //if you use jquery library
                //$("#recaptcha_v3").val(token);
            }
        });
    });
</script>

Where SITE_KEY was taken from recently modified .env file. Action – ‘ homepage ‘ is default action, you can change it on whatever you want, this action will be displayed in analytics later.

And add hidden input into form, to send our received token to backend.

<input type="hidden" name="recaptcha_v3" id="recaptcha_v3">

Overall should look like this:

<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">{{ __('Login') }}</div>

                <div class="card-body">
                    <form method="POST" action="{{ route('login') }}">
                        @csrf
 // default login form data here //
//hidden input here
<input type="hidden" name="recaptcha_v3" id="recaptcha_v3">
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
//added recaptcha script here
<script src="https://www.google.com/recaptcha/api.js?render={{env('G_RECAPTCHA_SITE_KEY')}}"></script>
<script>
    grecaptcha.ready(function() {
        grecaptcha.execute("{{env('G_RECAPTCHA_SITE_KEY')}}", {action: 'homepage'}).then(function(token) {
            if(token) {
                //js
                document.getElementById('recaptcha_v3').value = token;
                //if you use jquery library
                //$("#recaptcha_v3").val(token);
            }
        });
    });
</script>

Setup in Backend

And last one step is to check on backend if this form has been submitted real human or bot. In our case we need to rewrite basic Laravel Auth logic and add to Login controller, which is located in app/Http/Controllers/Auth directory, public login function:

public function login(Request $request)
{
    $vars = array(
        'secret' => env('G_RECAPTCHA_SECRET_KEY'),
        "response" => $request->input('recaptcha_v3')
    );
    $url = "https://www.google.com/recaptcha/api/siteverify";
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $vars);
    $encoded_response = curl_exec($ch);
    $response = json_decode($encoded_response, true);
    curl_close($ch);
    if($response['success'] && $response['action'] == 'homepage' && $response['score']>0.5) {
        //continue basic login logic
    } else {
        //then probably this is a bot
        //you can do your logic here pass it or deny or do something special
        //score check value of 0.5 you can set which you want form 0 to 1
        //score 1 is probably human score 0 is probably bot
    }
}

Please take attention on response success variable, on action variable to know if you trying to verify correct form and on score.

Original login function is located in this file: vendor/laravel/framework/src/Illuminate/Foundation/Auth/AuthenticatesUsers.php you can look on basic login logic there.

That is all, should work properly. If you have any questions you can ask them here, I will try to help you.

3 Comments found

User

anuj

really work

Reply
User

Ravi Khatana

I follow all steps, but {{env(‘G_RECAPTCHA_SITE_KEY’)}} all appear is null, I am not sure if by pageview can see this value or not. when DD in login controller
$request->input(‘recaptcha_v3’) and $response[‘success’] coming null

Reply
User

Alex B.

Ravi, maybe you have some issue with google site key getting from .env file. Try to include your google site key in you html template straightly, to check if it all works fine. After that, if all will works fine you can try to use google site key from .env file.

Reply

Add Comment

Your email address will not be published. Required fields are marked *