If, like me, you've had trouble installing the Python Imaging Library or FreeType, you may have also had trouble getting a captcha to work. Here's my quick and dirty workaround — be warned, this is very low level security, and shouldn't be used on high-profile sites.
Originally published at http://gregbrown.co.nz/code/django-captcha-without-freetype-or-pil/
Credit to the author of django-simple-captcha, from whom I borrowed most of this code.
Usage
from django import forms
from ABOVE-FILE import CaptchaField
class CaptchaTestForm(forms.Form):
myfield = forms.TextField()
security_check = CaptchaField()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | from django.forms.fields import CharField, MultiValueField
from django.forms.widgets import TextInput, MultiWidget, HiddenInput
from django import forms
from django.utils.safestring import mark_safe
import hashlib
import random
class CaptchaTextInput(MultiWidget):
def __init__(self,attrs=None):
widgets = (
HiddenInput(attrs),
TextInput(attrs),
)
super(CaptchaTextInput,self).__init__(widgets,attrs)
def decompress(self,value):
if value:
return value.split(',')
return [None,None]
def render(self, name, value, attrs=None):
ints = (random.randint(0,9),random.randint(0,9),)
answer = hashlib.sha1(str(sum(ints))).hexdigest()
#print ints, sum(ints), answer
extra = "What is %d + %d?" % (ints[0], ints[1])
value = [answer, u'',]
return mark_safe(extra + super(CaptchaTextInput, self).render(name, value, attrs=attrs))
class CaptchaField(MultiValueField):
widget=CaptchaTextInput
def __init__(self, *args,**kwargs):
fields = (
CharField(show_hidden_initial=True),
CharField(),
)
super(CaptchaField,self).__init__(fields=fields, *args, **kwargs)
def compress(self,data_list):
if data_list:
return ','.join(data_list)
return None
def clean(self, value):
super(CaptchaField, self).clean(value)
response, value[1] = value[1].strip().lower(), ''
if not hashlib.sha1(str(response)).hexdigest() == value[0]:
raise forms.ValidationError("Sorry, you got the security question wrong - to prove you're not a spammer, please try again.")
return value
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 10 months, 2 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 2 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
- Help text hyperlinks by sa2812 1 year, 6 months ago
Comments
Yeah, I linked to that in the description of this snippet... the point of this script is to provide a captcha which doesn't rely on freetype - it uses a plain text question (ie "What is 3 + 4?") instead of an image.
#
Please login first before commenting.