Dec. 3, 2024
CAPTCHA - who's on the other side?
Man or machine - that is the question. Currently, we are not sure if the request sent to the server is caused by human action. So the question remains how to verify the person who is in our corner of the Internet. A popular solution is to use reCAPTCHA from Google, but you don't have to be limited to one method. You can use other packages to distinguish between people and computers. Such a package is Django-simple-captcha, which requires Django version 1.8 or later; as the name implies, we can easily make only humans go further and robots staying behind doors that they cannot pass through.
After the standard installation described in the documentation, which can be found at the link provided, it's time to create a CAPTCHA. Let it be just a form that takes a name from a man who will also pass our test.
from Django.forms import ModelForm
from captcha.fields import CaptchaField
from .models import Human
class CaptchaForm(ModelForm):
captcha = CaptchaField()
class Meta:
model = Human
fields = [
'name',
'captcha'
]
The form will look like this:
You can of course handle success as well as failure, sample view:
from django.views.generic import FormView, TemplateView
from django.urls import reverse_lazy
from .forms import CaptchaForm
class CheckView(FormView):
template_name = 'check.html'
form_class = CaptchaForm
success_url = reverse_lazy('cap:human')
def form_valid(self, form):
#your code if human
return super().form_valid(form)
def form_invalid(self, form):
#your code if robot
return super().form_invalid(form)
class ThisIsHuman(TemplateView):
template_name = 'human.html'
If regular CAPTCHA is too boring, you can change it into simple math puzzles, make the font bigger or smaller, set different background colors, and rotate the text. Here are some sample CAPTCHAs that generated when modified variables:
CAPTCHA_IMAGE_SIZE
CAPTCHA_FONT_SIZE
CAPTCHA_LETTER_ROTATION
CAPTCHA_BACKGROUND_COLOR
Now let's create our own CAPTCHA, let it be a question about the dog's name, for a human the answer to this question will be obvious. We just need to return two strings, question and answer, the code will look like this:
import random
def my_super_captcha():
questions = []
answers = []
questions.append('Jak sie nazywa reksio?')
answers.append('reksio')
questions.append('Jak sie nazywa pluto?')
answers.append('pluto')
questions.append('Jak sie nazywa rex?')
answers.append('rex')
x = random.randint(0, len(questions)-1)
return questions[x], answers[x]
We randomize the questions and expect answers, now add the path to our randomizing function in settings.py, and it's ready.
CAPTCHA_CHALLENGE_FUNCT = 'cap.captcha_fun.my_super_captcha'
These are our questions. To proceed, you need to enter the dog's name correctly, and what will you ask? Your imagination only limits you.
I am often a robot for reCAPTCHA when I cannot decide whether a given tile still has traffic lights or not. If you don't want the user to think about their humanity, please do whatever CAPTCHA you feel is appropriate. There are many possibilities, and you can surprise the user with ingenious puzzles, which will make him remember your website as different from everything else on the web. The Django-simple-captcha package allows you to make a CAPTCHA as you like, try it yourself, and create unique tests quickly. Thanks to this, you will always know who is on the other side.