Creating captchas in Python #2

Once the script to generate captchas is set up (see previous post) this can be easily tied into a Python web page. This assumes you are using Werkzeug and Mako, but I’m sure Django/Pylons with Jinja etc won’t be too different. 

The code to display the image in the Mako template is below. For the image, the controller endpoint (blog.generateCaptcha) returns an image regardless of the image URL passed to it. However, you want the image URL to be unique so that if the user gets the captcha (or anything else) in the form wrong, a new captcha image is displayed. The same URL would result in caching of the old, now invalid, image.I use time.time() to make the image unique.

<% import time %>
<% img = "captcha" + str(time.time()) + ".jpg" %>
<p>
        <img src="${urls.build('blog.generateCaptchaImage', dict(id=img))|h}" alt="captcha" title="captcha image" />
</p>

The controller endpoint for the image:

def generateCaptchaImage(self, id):
        """ Generate a captcha. Store the word in self.captcha and return the image """
        word, image = generateCaptcha()
        self.captcha = word
        return Response(image, mimetype='image/jpeg')

Self.captcha is a property which stores and retrieves the captcha from the session. This is passed to the form validator along with the user’s inputs, and compared. If they are the same, then the user has the correct captcha.

I’m sure the captcha can be broken easily, and it’s not exactly the hardest thing to read (although this can be changed by making the font more awkward) but for the purposes of stopping simple spammers it works quite nicely.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s