Установка ReCAPTCHA в Django 4.1
Для установки в терминал введем следующую команду: pip install django-recaptcha
Результат:
(venv) PS C:\Users\Razilator\Desktop\Courses\App\backend> pip install django-recaptcha
Collecting django-recaptcha
Using cached django_recaptcha-3.0.0-py3-none-any.whl (22 kB)
Requirement already satisfied: django in c:\users\razilator\desktop\courses\app\venv\lib\site-packages (from django-recaptcha) (4.1)
Requirement already satisfied: asgiref<4,>=3.5.2 in c:\users\razilator\desktop\courses\app\venv\lib\site-packages (from django->django-recaptcha) (3.5.2)
Requirement already satisfied: tzdata in c:\users\razilator\desktop\courses\app\venv\lib\site-packages (from django->django-recaptcha) (2022.2)
Requirement already satisfied: sqlparse>=0.2.2 in c:\users\razilator\desktop\courses\app\venv\lib\site-packages (from django->django-recaptcha) (0.4.2)
Installing collected packages: django-recaptcha
Successfully installed django-recaptcha-3.0.0
Далее нам необходимо подключить модуль captcha
в backend/settings.py
backend/settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sites',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'mptt',
'debug_toolbar',
'captcha',
'modules.blog.apps.BlogConfig',
'modules.system.apps.SystemConfig',
]
Отлично. Теперь давайте получим необходимые ключи и добавим их в backend/settings.py
Переходим на сайт Google ReCAPTCHA

Нажимаем создать.
Я выбрал себе версию капчи 2.
Домен указал локальный для примера, на деплое вы указываете настоящий домен вашего сайта.

Получаю вот такие ключи:

И добавляем эти ключи в backend/settings.py (я добавил в самый низ, где мы настраивали SMTP в одном из уроков)
# ReCaptcha settings
RECAPTCHA_PUBLIC_KEY = '6Lc3Z1AhAAAAACf7fNueWxIXWjH117-wgbXGyykB'
RECAPTCHA_PRIVATE_KEY = '6Lc3Z1AhAAAAAAOjLoGOWA_kljXQaYO2CXGDt0ro'
Отлично. Рекапча подключена, теперь осталось модернизировать наши формы...
Давайте добавим ReCaptcha для регистрации, авторизации. Поэтому мы их модернизируем.
modules/system/forms/authenticated.py
from captcha.fields import ReCaptchaField
from captcha.widgets import ReCaptchaV2Checkbox
from backend import settings
class UserRegisterForm(UserCreationForm):
"""
Переопределенная форма регистрации пользователей
"""
class Meta(UserCreationForm.Meta):
fields = UserCreationForm.Meta.fields + ('email', 'first_name', 'last_name')
recaptcha = ReCaptchaField(widget=ReCaptchaV2Checkbox, public_key=settings.RECAPTCHA_PUBLIC_KEY,
private_key=settings.RECAPTCHA_PRIVATE_KEY, label='Капча')
def clean_email(self):
"""
Проверка email на уникальность
"""
email = self.cleaned_data.get('email')
username = self.cleaned_data.get('username')
if email and User.objects.filter(email=email).exclude(username=username).exists():
raise forms.ValidationError('Email адрес должен быть уникальным')
return email
def __init__(self, *args, **kwargs):
"""
Обновление стилей формы регистрации
"""
super().__init__(*args, **kwargs)
for field in self.fields:
self.fields['username'].widget.attrs.update({"placeholder": 'Придумайте логин'})
self.fields['email'].widget.attrs.update({"placeholder": 'Введите ваш email'})
self.fields['first_name'].widget.attrs.update({"placeholder": 'Ваше имя'})
self.fields["last_name"].widget.attrs.update({"placeholder": 'Ваша фамилия'})
self.fields['password1'].widget.attrs.update({"placeholder": 'Придумайте свой пароль'})
self.fields['password2'].widget.attrs.update({"placeholder": 'Повторите придуманный пароль'})
self.fields[field].widget.attrs.update({"class": "form-control", "autocomplete": "off"})
Пояснения:
- Я добавил поле с названием recaptcha и виджетом из нашего модуля, добавил ключи из настроек путем их импорта.
Делаю тоже самое для других форм:
modules/system/forms/authenticated.py
class UserLoginForm(AuthenticationForm):
"""
Форма авторизации на сайте
"""
recaptcha = ReCaptchaField(widget=ReCaptchaV2Checkbox, public_key=settings.RECAPTCHA_PUBLIC_KEY,
private_key=settings.RECAPTCHA_PRIVATE_KEY, label='Капча')
def __init__(self, *args, **kwargs):
"""
Обновление стилей формы регистрации
"""
super().__init__(*args, **kwargs)
for field in self.fields:
self.fields['username'].widget.attrs['placeholder'] = 'Введите ваш логин'
self.fields['password'].widget.attrs['placeholder'] = 'Введите ваш пароль'
self.fields['username'].label = 'Логин'
self.fields[field].widget.attrs.update({
'class': 'form-control',
'autocomplete': 'off'
})
class UserPasswordChangeForm(SetPasswordForm):
"""
Форма изменения пароля
"""
recaptcha = ReCaptchaField(widget=ReCaptchaV2Checkbox, public_key=settings.RECAPTCHA_PUBLIC_KEY,
private_key=settings.RECAPTCHA_PRIVATE_KEY, label='Капча')
def __init__(self, *args, **kwargs):
"""
Обновление стилей формы
"""
super().__init__(*args, **kwargs)
for field in self.fields:
self.fields[field].widget.attrs.update({
'class': 'form-control',
'autocomplete': 'off'
})
class UserForgotPasswordForm(PasswordResetForm):
"""
Запрос на восстановление пароля
"""
recaptcha = ReCaptchaField(widget=ReCaptchaV2Checkbox, public_key=settings.RECAPTCHA_PUBLIC_KEY,
private_key=settings.RECAPTCHA_PRIVATE_KEY, label='Капча')
def __init__(self, *args, **kwargs):
"""
Обновление стилей формы
"""
super().__init__(*args, **kwargs)
for field in self.fields:
self.fields[field].widget.attrs.update({
'class': 'form-control',
'autocomplete': 'off'
})
class UserSetNewPasswordForm(SetPasswordForm):
"""
Изменение пароля пользователя после подтверждения
"""
recaptcha = ReCaptchaField(widget=ReCaptchaV2Checkbox, public_key=settings.RECAPTCHA_PUBLIC_KEY,
private_key=settings.RECAPTCHA_PRIVATE_KEY, label='Капча')
def __init__(self, *args, **kwargs):
"""
Обновление стилей формы
"""
super().__init__(*args, **kwargs)
for field in self.fields:
self.fields[field].widget.attrs.update({
'class': 'form-control',
'autocomplete': 'off'
})
Наконец, давайте обезопасим добавление статей на сайт:
modules/blog/forms/articles.py
from captcha.fields import ReCaptchaField
from captcha.widgets import ReCaptchaV2Checkbox
from backend import settings
class ArticleCreateForm(forms.ModelForm):
"""
Форма добавления статей на сайте
"""
class Meta:
model = Article
fields = (
'title',
'slug',
'category',
'short_description',
'full_description',
'thumbnail',
'meta_title',
'meta_keywords',
'meta_description',
'is_published',
)
recaptcha = ReCaptchaField(widget=ReCaptchaV2Checkbox, public_key=settings.RECAPTCHA_PUBLIC_KEY,
private_key=settings.RECAPTCHA_PRIVATE_KEY, label='Капча')
def __init__(self, *args, **kwargs):
"""
Обновление стилей формы
"""
super().__init__(*args, **kwargs)
for field in self.fields:
self.fields[field].widget.attrs.update({
'class': 'form-control',
'autocomplete': 'off'
})
self.fields['meta_title'].widget.attrs.update({
'placeholder': 'Введите мета-название для поисковой системы'
})
self.fields['title'].widget.attrs.update({
'placeholder': 'Заголовок статьи'
})
self.fields['slug'].widget.attrs.update({
'placeholder': 'Ссылка статьи (необязательно)'
})
self.fields['meta_description'].widget.attrs.update({
'placeholder': 'Введите небольшое описание в 300 символов для поисковой системы'
})
self.fields['meta_keywords'].widget.attrs.update({
'placeholder': 'Введите ключевые слова через запятую для поиска'
})
self.fields['category'].empty_label = 'Выберите категорию'
self.fields['is_published'].widget.attrs.update({
'class': 'form-check-input'
})
Смотрим на результат, пробуем авторизоваться без проверки капчи:

После проверки:

И входим успешно на наш сайт!

Для безопасности создания статей я также с вами добавил рекапчу.

Отлично. На этом урок завершен, мы хоть немного, но обезопасили наш сайт от лишнего спама. Поверьте, рекапча и вправду спасает. Особенно в обратной связи, которую мы создадим в следующем уроке.