Создание сайта на Django: Урок 33, добавление ReCAPTCHA в Django для защиты от спама
avatar
7 | (offline)
❤️‍🔥Notehunter Developer
Добавлено:
Категория: Руководства «Django»
Комментариев: 0

Установка 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'
            })

Смотрим на результат, пробуем авторизоваться без проверки капчи:

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

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

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

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

Комментарии к статье 0
Комментариев нет
Форма добавления комментария (необходима регистрация)