-
Добрый вечер.
Пишу простой класс, которая отвечает за проверку и ограничение доступа при нескольких неудачных попытках его совершения (н-р: для защиты от подбора пароля).
Остановился на том, что блокироваться будет пользователь по IP и в качестве хранилища будет memcached (жалею БД).
Все готово, но не хватает простой проверки: а включено ли кэширование проекта при помощи мэмкеш?
В голову приходят 2 пути:
- указывать в конфиге MEMCACHED = True (отвратительный вариант, мы же указываем кэширование в CACHE_BACKEND, зачем дублировать?)
- парсить settings.CACHE_BACKEND на предмет наличия в ней memcached:// (тоже кажется кривым решением).
Идеальное решение - получить эту информацию от Джанго. По идее - задача очевидная, но на практике, как и откуда это получить я не нашел.
Заранее благодарю за помощь. -
Можно еще
, а потом проверять type(cache).from django.core.cache import cache
Внутри Django все равно парсит settings.CACHE_BACKEND, так что можно и самому смотреть settings.CACHE_BACKEND на предмет наличия там memcached://, я думаю. -
Парсинг видел, именно потому очень не хочется его повторять.
Т.е., нет никакого cache.type, который вернет тип кэширования? обЫдно. -
Я бы сказал, что вы ищете красоту в том месте, где ее быть не может. Кеш по сути своей — не хранилище, потому что он опционален, может протухать или сбрасываться в любой момент. Поэтому семантика работы приложения не должна зависеть от кеша. Если его оторвать, приложение должно продолжать работать дальше корректно, хоть и медленно.
Мне кажется, БД для хранения таких вещей более чем подходит. "Жалеть" ее как-то незачем.
-
Если говорить о кэше в классическом его понимании - да, согласен и поддерживаю.
Если говорить о memcached, то его давно и весьма успешно используют как хранилище некритичной, часто используемой информации, потеря которой не приведет к проблемам у приложения. Именно потому я и хочу делать проверку, какой из способов кэширования используется.
Представим себе ситуацию. Кто-то решил подобрать пароль. В этой ситуации, мы легко можем получить 100 запросов в секунду к форме авторизации. И на каждый из этих запросов делать коннект к базе данных, делать выборку из таблицы (пусть и небольшой) по ip. Нагрузка будет ощутимая. А если таких "хакеров" будет несколько?
Не проще ли хранить этот лог в кэше, избегая тем самым лишней нагрузки к БД (если человек в бане, то дело не доходит до коннекта к БД), тем более что падение кэша приведет лишь к тому, что все заблокированные пользователи будет разблокированы, но само приложение будет полностью работоспособно?
Я готов признать свою неправоту, если вы мне объясните другие действующие пути решения подобных задач. Я буду только рад новым знаниям. -
Если мотив в том, чтобы использовать memcached как общедоступное хранилище, то тогда к нему, может быть, просто не стоит обращаться через API кеширования. Вместо этого стоит написать собственный код, который будет обращаться к memcached напрямую, и при этом либо требовать, чтобы memcached был, либо тихо игнорировать его отсутствие:
import memcache cache = memcache.Client(['127.0.0.1:11211']) count = cache.get(ip) or 0 result = cache.set(ip, count + 1, time=15) if result == 0: # memcache не работает if count > MAX_COUNT: return HttpForbiddenResponseТак можно, например, использовать отдельный instance кеша, чтобы данные в нем не протухали из-за жизни в системе. А можно и из настроек выпарсить, что не шибко сложно.


