androidcodeexamples.com
Offcode ltd logo
ANDROID
APACHE
THUMBNAILS
SCRIPTS
GFX
World-class examples brought to you by Offcode ltd
APACHE
Getting started Upload to server Image server Image manipulation Image cache reCAPTCHA Front Page
androidcodeexamples.com

Handling reCAPTCHA with a shell script

reCAPTCHA view
reCAPTCHA view

Here we'll show you how to implement a reCAPTCHA verifier with a simple linux shell script. It uses curl for sending the data to Google's server which then replies the final verdict. If the submit button in pressed again, Google finds it's a duplicate and we get an error as well. All in all, this is quite a robust way of sorting out the bots that wish to spam.

We use ajax for sending the request. Using plain submit will tend to direct to a new page which will cause unnecessary trouble. Now we just get the response code and thus determine if this was a success. This is a sample commenting section using Google's reCAPTCHA. We expect you have registered reCAPTCHA services in Google already.


HTML AJAX script code for reCAPTCHA

This is how the HTML script section code looks like:

<script src="https://www.google.com/recaptcha/api.js?render=explicit&onload=onScriptLoad" async defer></script>
function comments() {
    $.ajaxSetup({ cache: false });
    $("#div_comments").load("comments/page.html");
    $("#comment").submit(function(event) {
        event.preventDefault();
        var token = window.grecaptcha.getResponse(recaptchaId);

        if (!token) {
            alert("Please confirm you're not a bot!");
            return;
        }

        var formData = $('input#name').val();
        formData += "%_&_%";
        formData += $('textarea#feedback').val();
        var uploadData = formData+"g-recaptcha-response="+token;
        console.log(uploadData);
        $.ajax({
              url: '/s/comment',
              type: 'POST',
              data: uploadData,
            }).done(function(data) {
              console.log(data);
              grecaptcha.reset();
              $.ajaxSetup({ cache: false });
              $("#div_comments").load("/comments/page.html");
            }).fail(function(data) {
              alert("Error sending the feedback");
              grecaptcha.reset();
        });
    });
}
window.onScriptLoad = function () {
    var htmlElement = document.querySelector('.g-recaptcha');

    var captchaOptions = {
      sitekey: 'ThisIsYourSiteKeyFromGoogleDontUseThis',
      callback: window.onUserVerified
    };

    recaptchaId = window.grecaptcha.render(htmlElement, captchaOptions, true);
};

window.onUserVerified = function (token) {
    console.log('token=', token);
};

Your html body:

<body onload="comments();">

HTML code for the ajax script

The code below is the HTML portion of the page. It declares a simple form:

<div id="div_comments">
</div>

<div class="text-xs-center">
<form id="comment">
  <input id="name" type="text" name="name" placeholder="Name"/><br>
  <textarea id="feedback" name="feedback" placeholder="Your comment"></textarea>
  <div class="g-recaptcha" data-sitekey="thisIsYourSiteKeyFromGoogleDontUseThis" data-size="compact"></div>
  <input type="submit" name="submit" value="Submit" />
</form>
</div>


Shell script for verifying the reCAPTCHA

The shell script below gets the AJAX post feedback with the appropriate data. The curl command sends all what's required to Google's server for verification. Eventually, if this output is a success (or failure), it echoes a simple echo "Status: 204 No Content". In a failure case, an error alert is seen on the screen. Please note that if you have a lot of concurrent users, this script updating the HTML will not work well. You'd need to use flock to serialize the access. Let's first create the script with our favorite text editor (pico!):

root@server261583:/usr/lib/s# pico comment

The file 'comment' would look like the one below. It appends to a file /var/www/html/comments/page.html. See the CSS of this file for the details.

#!/bin/bash

HTMLREF="page.html"
cd /home/imageserviceagent/comments 2>/dev/null > /dev/null

if [ $? -eq 0 ]; then
  FILEN=`/bin/mktemp -u XXXXXXXX`
  /bin/dd count=$CONTENT_LENGTH bs=1M 2>/dev/null > comment_$FILEN.bin
  # Remove all lines until match, and all before the match
  RESPONSE=`cat comment_$FILEN.bin | sed -n '/g-recaptcha-response=/,$p' | sed 's/^.*g-recaptcha-response=//' | sed 's/\&submit=Submit//'`
  # For your debug purposes
  echo "$RESPONSE" > resp_$FILEN.txt

  TOTAL=`stat -c%s comment_$FILEN.bin`
  RESP_SIZE=`stat -c%s resp_$FILEN.txt`
  TO_REMOVE=$((TOTAL-RESP_SIZE))
  TO_REMOVE=$((TO_REMOVE-20))

  GOOGLE_REPLY=`curl -X POST --data-binary "secret=YOUR-SECRET-FROM-GOOGLE-XT9uuTgC1aN7fazyn27E6&response=$RESPONSE" https://google.com/recaptcha/api/siteverify`
  echo "$GOOGLE_REPLY" | grep "\"success\": true," 2>/dev/null >/dev/null
  if [ $? -eq 0 ]; then
    echo "" >> /var/www/html/comments/$HTMLREF

    COMMENT=`head -c $TO_REMOVE comment_$FILEN.bin | sed 's/^.*\%_\&_\%//' | recode utf-8..html`
    NAME=`head -c $TO_REMOVE comment_$FILEN.bin | sed -n 's/\%_\&_\%.*//p' | recode utf-8..html`


    echo "<div class=\"comment_area\">" >> /var/www/html/comments/$HTMLREF

    echo "  <div class=\"comment_name\">" >> /var/www/html/comments/$HTMLREF
    echo "    $NAME:" >> /var/www/html/comments/$HTMLREF
    echo "  </div>" >> /var/www/html/comments/$HTMLREF

    echo "  <div class=\"comment_field\">" >> /var/www/html/comments/$HTMLREF
    echo "    $COMMENT" >> /var/www/html/comments/$HTMLREF
    echo "  </div>" >> /var/www/html/comments/$HTMLREF

    echo "  <div class=\"comment_date\">" >> /var/www/html/comments/$HTMLREF
    echo "  <sub>" >> /var/www/html/comments/$HTMLREF
    date -R >> /var/www/html/comments/$HTMLREF
    echo "  </sub>" >> /var/www/html/comments/$HTMLREF
    echo "  </div>" >> /var/www/html/comments/$HTMLREF
    echo "</div>" >> /var/www/html/comments/$HTMLREF

    echo "Status: 204 No Content"
    echo ""

    exit
  fi

  echo "$GOOGLE_REPLY" >> error.txt
  if [ -f comment_$FILEN.bin ]; then
    rm comment_$FILEN.bin 2>/dev/null >/dev/null
  fi
  if [ -f resp_$FILEN.txt ]; then
    rm resp_$FILEN.txt 2>/dev/null >/dev/null
  fi
fi
echo "Status: 204 No Content"
echo ""
# This propagates an error

Curl command for Google reCAPTCHA

Let's have a detailed look at the curl command we just used.

GOOGLE_REPLY=`curl -X POST --data-binary "secret=YOUR-SECRET-FROM-GOOGLE-XT9uuTgC1aN7fazyn27E6&response=$RESPONSE" https://google.com/recaptcha/api/siteverify`

Between "secret= and &response= you must put your secret from the Google reCAPTCHA console. $RESPONSE contains the response we just parsed with the sed.


Test automated commenting section working!

Feel free to play around with this! I will delete some if this gets large. Hope this helps!



Written on April 2018 by Eero Nurkkala. Updated Nov 23rd, 2018.

contact information