Setting up Google reCAPTCHA with the Slim 3 Framework and Ajax

... by Bittle in Slim 3 Framework February 24, 2019

Purpose

Hate getting spam to your email from your contact form? Yeah, me too. Let's stop these bots with some good Google CAPTCHA! An example of this can be found in the contact form of this website.


Getting keys

Go to https://www.google.com/recaptcha/admin to get version 2 of reCAPTCHA or https://g.co/recaptcha/v3 for version 3. Google will provide you with 2 keys, 1 is for your html form, and the other is for your backend.


Setting up the form

Add Google recaptcha's external javascript file to your website (in the head tag or before your body tag ends)

<script src='https://www.google.com/recaptcha/api.js'></script>


Then create a form with the reCAPTCHA code:

<div class="g-recaptcha" data-sitekey="front-end-secret-key"></div>


The form in the contact page of this website uses the current html:

view.php
<form class="form-horizontal" id="contact-form" method="post" action="">
  <fieldset class="container">
    <div class="form-group row">
      <label for="inputEmail" autocomplete="false" class="col-lg-2 control-label">Email</label>
      <div class="col-lg-9">
        <input type="email" class="form-control" id="inputEmail" placeholder="Email" name="email"> </div>
    </div>
    <div class="form-group row">
      <label for="textArea" class="col-lg-2 control-label">Message</label>
      <div class="col-lg-9">
        <textarea class="form-control" rows="3" id="textArea" placeholder="Your message..." name="message"></textarea>
      </div>
    </div>
    <div class="form-group row">
      <div class="col-lg-2"></div>
      <div class="col-lg-9">
        <div class="g-recaptcha" data-sitekey="front-end-secret-key"></div>
      </div>
    </div>
    <div class="form-group row justify-content-end">
      <div class="col-lg-10">
        <button type="submit" class="btn btn-raised btn-primary">Submit</button>
        <button type="button" class="btn btn-danger">Cancel</button>
      </div>
    </div>
  </fieldset>
</form>

Thing to note here is that your reCAPTCHA is part of the form, and that the key is used in the tag "data-sitekey".


Making The Call

contact.js
$(function() {
  $('#contact-form').on('submit', function(e) {
    $.ajax({
      type: "POST",
      url: "",
      dataType: "json",
      data: {
        email: $('#inputEmail').val(),
        message: $('#textArea').val(),
        captcha: grecaptcha.getResponse()
      },
      success: function(data) {
        console.log(data);
      }
    });
    return false;
  });
});

Note that the captcha is being passed to the back-end with the ajax call, we will verify this with Google in the back-end with Slim.


Receiving The Call

The Ajax call will call a route in the back-end. My form calls it's current route "/contact". The route looks something like the following:

App.php
$app->post('/contact', function ($request, $response, $args) {
    $params = $request->getParsedBody();

    if (!filter_var($params['email'], FILTER_VALIDATE_EMAIL) ||
          $params['message'] == "" || $params['message'] == null) {
        return $response->withJson(['success'=>false, 'msg'=>'Invalid data']);
    }

    // check captcha
    $secret = "back-end-key";
    $captcha = $params['captcha'];


    $verify=file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret={$secret}&response={$captcha}");
    $captcha_success=json_decode($verify);


    if ($captcha_success->success==false) {
        return $response->withJson(['success'=>'false', 'msg'=>'Are you a robot?']);
    }

    // do something once you know its not a robot
    // $arr = \app\utils\Mail::contactUs($params['email'], $params['message']);
    return $response->withJson($arr);
});

Replace $secret with your own back-end key


There you go! Of course this was only a short tutorial without any real user validation. Make your own adjustments as needed :) Happy coding.

Comments (0)

Search Here