Добавление ReCAPTCHA для форм
Зачем капча
Открытые формы — регистрация, обратная связь, сброс пароля — быстро находят боты: создают тысячи аккаунтов и рассылают спам. reCAPTCHA от Google отличает людей от программ.
| Версия | Как выглядит |
|---|---|
| v2 Checkbox | Галочка «Я не робот», иногда задание с картинками |
| v2 Invisible | Без галочки, задание только при подозрении |
| v3 | Полностью невидимая, возвращает оценку 0.0–1.0 |
Ключи
- Откройте консоль администратора reCAPTCHA (google.com/recaptcha/admin).
- Выберите тип (например, v2 «Я не робот») и добавьте домены: ваш домен и
127.0.0.1для разработки. - Получите ключ сайта (публичный, попадает в HTML) и секретный ключ (только на сервере).
Ключи — в переменные окружения (файл .env, не в git):
import os
RECAPTCHA_PUBLIC_KEY = os.getenv("RECAPTCHA_PUBLIC_KEY")
RECAPTCHA_PRIVATE_KEY = os.getenv("RECAPTCHA_PRIVATE_KEY")
Установка
pip install django-recaptcha
INSTALLED_APPS = [
...
"django_recaptcha",
]
Имя приложения
В старых версиях пакета (до 4.0) приложение называлось captcha и импорты были из captcha.fields. Сейчас — django_recaptcha.
Поле в форме
from django_recaptcha.fields import ReCaptchaField
from django_recaptcha.widgets import ReCaptchaV2Checkbox
class UserRegisterForm(UserCreationForm):
recaptcha = ReCaptchaField(widget=ReCaptchaV2Checkbox)
...
Обычное поле формы: в шаблоне выводится {{ form.recaptcha }} (или вместе со всей формой), а проверка выполняется в form.is_valid() — Django отправляет токен из формы и секретный ключ в API Google. Не прошёл — ошибка поля.
Невидимая v3 с порогом:
from django_recaptcha.widgets import ReCaptchaV3
recaptcha = ReCaptchaField(widget=ReCaptchaV3(action="signup", required_score=0.5))
Форма обратной связи с капчей
class FeedbackCreateForm(forms.ModelForm):
recaptcha = ReCaptchaField(widget=ReCaptchaV2Checkbox)
class Meta:
model = Feedback
fields = ("subject", "email", "content")
То же — в PasswordResetView через свою форму:
class UserPasswordResetForm(PasswordResetForm):
recaptcha = ReCaptchaField(widget=ReCaptchaV2Checkbox)
path("password-reset/", auth_views.PasswordResetView.as_view(form_class=UserPasswordResetForm, ...)),
Тесты и разработка
Без ключей пакет использует тестовые ключи Google (капча всегда проходит) и пишет предупреждение в консоль. В тестах заглушите проверку:
SILENCED_SYSTEM_CHECKS = ["django_recaptcha.recaptcha_test_key_error"]
С тестовыми ключами Google принимает любое непустое значение g-recaptcha-response, но запрос в интернет всё равно уходит. В автотестах надёжнее подменить проверку через unittest.mock.patch на ReCaptchaField.validate.
Итог
- Капча защищает формы регистрации, обратной связи и сброса пароля.
- Пакет
django-recaptcha: приложениеdjango_recaptcha, полеReCaptchaFieldс виджетом v2 или v3. - Ключи — в переменных окружения; секретный ключ никогда не попадает в HTML.
- Проверка — на сервере, в
form.is_valid().
Практика решено 0 из 5
Добавьте в форму UserRegisterForm поле капчи recaptcha типа ReCaptchaField с виджетом ReCaptchaV2Checkbox.
Не забудьте импорты из django_recaptcha.fields и django_recaptcha.widgets.
from django_recaptcha.fields import ReCaptchaField
from django_recaptcha.widgets import ReCaptchaV2Checkbox
class UserRegisterForm(UserCreationForm):
recaptcha = ReCaptchaField(widget=ReCaptchaV2Checkbox)
Пропишите ключи в settings.py, читая их из переменных окружения:
RECAPTCHA_PUBLIC_KEY = os.getenv("RECAPTCHA_PUBLIC_KEY") и RECAPTCHA_PRIVATE_KEY = os.getenv("RECAPTCHA_PRIVATE_KEY").
import os
RECAPTCHA_PUBLIC_KEY = os.getenv("RECAPTCHA_PUBLIC_KEY")
RECAPTCHA_PRIVATE_KEY = os.getenv("RECAPTCHA_PRIVATE_KEY")
Чем reCAPTCHA v3 отличается от v2 «Я не робот»?
Где выполняется окончательная проверка капчи?
Каким формам сайта статей стоит добавить капчу?
Войдите, чтобы отмечать пройденные уроки.