я использую django-brake
и memcached
@ratelimit(field='email', method='POST', rate='5/m')
@ratelimit(field='email', method='POST', rate='10/h')
@ratelimit(field='email', method='POST', rate='20/d')
def login_failure(request, login_form):
"""
Increment cache counters, 403 if over limit.
"""
was_limited = getattr(request, 'limited', False)
if was_limited:
limits = getattr(request, 'limits', [])
login_form.full_clean()
login_form._errors.setdefault(NON_FIELD_ERRORS, ErrorList())\
.append('accout locked, try '+ str(limits[0]['period']) + ' seconds later')
return render(request, 'user/login.html', {'form': login_form})
def login(request):
if request.method == 'GET':
next = request.GET.get('next', '')
return render(request, 'user/login.html', {'next': next})
elif request.method == 'POST':
login_form = LoginForm(request.POST)
# check first
from brake.utils import get_limits
limits = get_limits(request, 'login_failure', 'email', [60, 3600, 86400])
if limits:
login_form.full_clean()
login_form._errors.setdefault(NON_FIELD_ERRORS, ErrorList())\
.append('accout locked, try '+ str(limits[0]['period']) + ' seconds later')
return render(request, 'user/login.html', {'form': login_form})
if login_form.is_valid():
email = login_form.cleaned_data['email']
submit_pwd = login_form.cleaned_data['password']
user = authenticate(username=email, password=submit_pwd)
if user is None:
#
res = login_failure(request, login_form)
if res is None:
login_form._errors.setdefault(NON_FIELD_ERRORS, ErrorList()).append('password wrong')
res = render(request, 'user/login.html', {'form': login_form})
return res
...
login etc...
else:
...