index-1-1.jpg
  • Aurora Solutions

Grails & reCAPTCHA


What is reCAPTCHA?

reCAPTCHA is a powerful service to detect against spam & abuse and can very easily help your distinguish between an actual site visitor or a bot. reCAPTCHA is a free service provided by Google and can be very easily set up in your web application.

reCAPTCHA with Grails

In this post I am going to show you how to set up reCAPTCHA in your Grails web application. For this tutorial I am going to use the sample application developed for the Simple Authorisation Tutorial by Andrew Stratton. We will just add the reCAPTCHA to the login page in this application.


Configuration:

To start off, you need to sign up for an API key pair for your site from Google's reCAPTCHA admin panel. The key pair consists of a site key (your public key) and secret (your private key). We will use the public key to display the reCAPTCHA widget on our login page. The private key will be used to authorize communication between our application backend and the reCAPTCHA server to verify the user's response.


When you are using reCAPTCHA, you need to understand that all of its access keys work on "localhost" (or "127.0.0.1"), so you can always develop and test on your local machine. But, it is critical to note that when you move to the staging or production environment; you must get new keys from the reCAPTCHA admin panel for that specific domain.


Generating keys for yourself is a self explanatory process. After you are done; you will get the key pair which would be something like: Code Changes:

Once you have your keys, all you have to do is make changes to the view & controller in your grails application. In the sample application we are using; add the following code to the <head> tag of your login.gsp page:

<r:script disposition="head">
    var RecaptchaOptions = {
        theme:'white'
    };

    $(document).ready(function () {
        $('#reset_password input[name="username"]').focus();
        $(document).keypress(function (e) {
            if (e.which == 13) {
                $(this).blur();
                $('#reset_password form').submit();
            }
        });
    });
</r:script>
<style type="text/css">
    #recaptcha_widget_div label {
        float: none;
    }

    #recaptcha_widget_div a img {
        top: 0px;
        left: 0px;
    }

    #recaptcha_widget_div span {
        font-weight: normal;
    }

    #recaptcha_widget_div {
        margin-left: 85px;
        margin-top: 12px;
    }
</style>

And, and the following piece of code where you want the reCAPTCHA widget to be displayed:

<tr>
    <script type="text/javascript"    src="https://www.google.com/recaptcha/api/challenge?k=<public key>">
    </script>
    
    <noscript>
        <iframe src="https://www.google.com/recaptcha/api/noscript?k=<public key>" height="300" width="500" frameborder="0"></iframe><br>
        <textarea name="recaptcha_challenge_field" rows="3" cols="40">
        </textarea>
        <input type="hidden" name="recaptcha_response_field" value="manual_challenge">
    </noscript>
</tr>

Note: The <public key> must be replaced with your public key


Next, we need to take the user’s response and verify it from Google’s reCAPTCHA server. To do that, add the following lines of code in the doLogin method of the UserController.

boolean result
def remoteAddress = request.remoteAddr
def body = [privatekey: "<private key>",
            remoteip: remoteAddress,
            challenge: params.recaptcha_challenge_field,
            response: params.recaptcha_response_field]
def http = new HTTPBuilder('https://www.google.com')
http.request(Method.POST, ContentType.TEXT) {
    uri.path = '/recaptcha/api/verify'
    uri.query = body
    body = body
    response.success = { resp, value ->
            StringWriter writer = new StringWriter()
            IOUtils.copy(value, writer)
            result = Boolean.parseBoolean((writer?.toString()?.split("\n") as List)[0])
    }
}

Note: The <private key> must be replaced with your private key


Now, you can use the result to display any validation message you want. For example;

if (result) {
    if (user) {
        redirect(controller:'plant',action:'list')
    } else {
        redirect(controller:'user',action:'login')
    }
} else {
    flash.error = message(code: 'forgotPassword.captcha.wrong')
    redirect(controller:'user', action:'login')
}

Result:

The result is that when you go to the http://localhost:8080/<app-name>/user/login page, you can see the reCAPTCHA:

It is a simple process and an easy to use implementation. For more information; visit https://developers.google.com/recaptcha/


Source Code:

The final code for the application can be found here.


Plugin:

If you have a grails application with version 2.0+ then you can look into this plugin as well.

0 views0 comments

Recent Posts

See All

GORM Feature of Grails

This article will explain Grails Object Relational Mapping feature and Grails relationship mapping such as one-to-one, one-to-many, many –to-many. Grails is known as domain driven language that means

Grails: Validating Domain Object

In this series of articles I am going to talk about the validations or constraints that can be added to Grails domain objects so that any junk data should not get stored to the database and hence our

Domain Relationships in Grails

In this article I am going to talk about how associations between domain objects are used in Grails. Grails is known as domain driven language that means we can build application using bottom to top a