@David5

Банить по IP на время?

Здравствуйте, у меня есть форма (закреп фотка) нужно чтобы после отправки формы, IP этого чела банилось на некоторое время,он мог просматривать сайт но при отправки формы ничего не происходило или ему выдавалсь ошибка что осталось столько-то времени.Это нужно для того чтобы, мне всякие умники не заспамили левыми заявками админку.5e3d376163420503398412.png
  • Вопрос задан
  • 311 просмотров
Решения вопроса 1
sergey-gornostaev
@sergey-gornostaev Куратор тега Django
Седой и строгий
Подключаете примерно такую мидлварь
def _get_ending(n, endings):
    n = n % 100
    if n >= 11 and n <= 19:
        return endings[2]
    else:
        n = n % 10
        if n == 1:
            return endings[0]
        elif n > 1 and n < 5:
            return endings[1]
        else:
            return endings[2]


def _get_message(limit):
    if limit > 3660:
        limit //= 3600
        endings = [_('часа'), _('часов'), _('часов')]
    elif limit > 60:
        limit //= 60
        endings = [_('минуты'), _('минут'), _('минут')]
    else:
        endings = [_('секунды'), _('секунд'), _('секунд')]
    return _('Форма отправлялась менее {} {} назад').format(limit, _get_ending(limit, endings))


def post_limit_middleware(get_response):
    limits = getattr(settings, 'REQUEST_LIMITS', {})

    def middleware(request):
        if request.method == 'POST':
            match = resolve(request.path_info)
            name = '{}:{}'.format(match.namespace, match.url_name) if match.namespace else match.url_name
            limit = limits.get(name)
            if limit is not None:
                now = datetime.now()
                user_id = request.user.username if request.user.is_authenticated else get_ip(request)
                key = hashlib.md5(user_id.encode()).hexdigest()
                cache_name = 'last-request.{0}.{1}'.format(name, key)
                last_request = cache.get(cache_name, now - timedelta(days=1))
                if (now - last_request) < timedelta(seconds=limit):
                    cache.set(cache_name, now)

                    if request.is_ajax():
                        response = JsonResponse([_get_message(limit)], safe=False)
                        response.status_code = 429
                    else:
                        response = render(request, '429.html', {'message': _get_message(limit)})
                        response.status_code = 429
                    return response
                else:
                    cache.set(cache_name, now)
        response = get_response(request)
        return response

    return middleware

Прописывается в settings.py настройку вида
REQUEST_LIMITS = {
    'contact_form': 3600,
}

И живёте спокойно.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
fox_12
@fox_12 Куратор тега Django
Расставляю биты, управляю заряженными частицами
Если используете кеш - я бы поступил проще. При условии что в ip - ip-адрес:
from django.core.cache import cache

IP_KEY = 'request_ban:{ip}'
DELAY = 3600

result = cache.get(IP_KEY.format(ip=ip))
if result:
     difference = (result - datetime.datetime.now()).seconds
     print(f'Вам осталось {difference} секунд')
else:
     cache.set(
          IP_KEY.format(ip=ip),
          datetime.datetime.now() + datetime.timedelta(seconds=DELAY),
          DELAY,
     )
     print('Добро пожаловать!')
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы