Protecting Plone Registration Forms with ReCAPTCHA

We recently launched the CIOC Community Site running on Plone. While we have not actually had any SPAM on the site yet, we continually get automated SPAM registrations that we then need to go and clear out. Last night Kate got fed up, so I decided to see if I could put a CAPTCHA on the form.

Looks like there is a proposal to include CAPTCHA support. The de facto standard CAPTCHA tool for Plone seems to be collective.captcha, but I wanted to be able to use the ReCAPTCHA service.

Luckily there is collective.recaptcha which is in beta and, while not listing any releases on the Plone site, is available from the Cheese Shop. But, alas, there is no documentation. It is supposed to be a drop in replacement for collective.captcha so with a little sleuthing and I got it to work. Here’s how.

Installation

I am using the unified Unix installer so everything is done via buildout. Following the instructions on the collective.captcha page we need to add collective.recaptcha to your eggs list and collective.recaptcha to your zcml list. Then run ./bin/buildout and restart your Plone instance.

Configuration

We need to enter our private and public ReCAPTCHA keys in the collective.recaptcha setup form which is located at http://urltoyourplonesite.com/recaptcha-settings

Registration Form Modifications

Using this site as a helpful reference I was able to figure out the additions I needed to make to the registration form and validator.

You need to go in through your Plone site setup into the Zope Management Interface. Navigate to portal_skins/plone_login. Click join_form and then the customize button. You should now be able to customize the form contents. Down near the bottom of the form there is a line:

<div class="formControls"></div>

Above that line you need to add:

<div class="field"
     tal:define="error errors/captcha|nothing;"
     tal:attributes="class python:test(error, 'field error', 'field')">
  <label for="captcha" i18n:translate="label_captcha">Captcha</label>
 
  <span class="fieldRequired" title="Required"
        i18n:attributes="title"
        i18n:domain="plone"
        i18n:translate="label_required">(Required)</span>
 
  <div class="formHelp" i18n:translate="help_captcha">
    Provide the text in the image. Just to avoid spambots
  </div>
  <p tal:replace="structure here/@@captcha/image_tag" />
 
</div>

Note that the difference from the code provided by Mikel Larreategi is that ReCAPTACH provides the input element itself, so you need to omit the div that includes the <input type="text"> tag.

Once you have that saved, you need to go back to portal_skins/plone_login and click join_form_validate and once again click customize. At the bottom of the validation code, just before

return state

add:

captcha = context.REQUEST.get('recaptcha_response_field')
view = context.restrictedTraverse('@@captcha')
 
if not view.verify(captcha):
    state.setError('captcha', _(u'Are you a bot? Try again...'))
    state.set(status='failure')

Note that the difference in the validation code from Mikel Larreategi’s is that the ReCAPTCHA inserted input tag is called recaptcha_response_field and not captcha.

Hopefully that is helpful to someone other than me :)

Tags:

8 Responses to “Protecting Plone Registration Forms with ReCAPTCHA”

  1. ok Says:

    Welcome to 2006, plone

  2. Christopher Lambacher Says:

    @ok I am not exactly sure what the point of that comment was. I’ll just have to assume that you enjoy posting troll comments to sites you find via reddit.

    For the record, there were some other options that allowed for the use of ReCAPTCHA, but none looked like they were likely to be as easy to get going and have continued long term support.

    Also, I could have rolled my own ReCAPTCHA support pretty easily which is probably what a lot of people do. It’s not exactly hard.

  3. John Bruce Says:

    This was EXACTLY what I needed! I was able to get reCAPTCHA up and running in about 10 minutes on the login form. The interesting part was getting it working on the sendto form (“mail this page to someone”).

    I created a custom validator and attached it to the sendto_form in the ZMI. You could easy reuse that form across any form that needed captcha validation!

  4. William Says:

    The geek is strong with this one.

  5. MichaelT Says:

    Thanks – it was helpful for me.

    BTW – you really attract some strange comments. A plone product for checking the sanity of the commentator might be useful.

    What does “The geek is strong with this one.” mean??

  6. Christopher Lambacher Says:

    @John Bruce & @MichealT glad you found it useful.

    @MichealT That’s William’s strange sense of humour. He’s a friend I see regularly in person, so it’s not an anonymous drive by comment like @ok’s :)

  7. Elliott Says:

    I, too, found this to be precisely what I needed to do to get reCaptcha working for me on registration forms. Thanks so much for taking the time to write such clear instructions for the uninitiated.

    I’ve found modifying Plone to be daunting and frankly strange, but useful how-to’s, like yours, really help to clear up the confusion.

    Do you have any other outlines that would be useful in simple blogs?

    Cheers!

  8. John Bruce Says:

    This is an absolutely fantastic article and it has been tremendously helpful, however I think it would be good to clarify is this article is about collective.captcha or collective.recaptcha. The link above takes me to the collective.captcha doc page, but i think the tutorial is referring to the collective.recaptcha plugin.

    Thanks for doing the footwork here!

    John

Leave a Reply