Django - Implement show CAPTCHA on 3 failed login attempts

965 views Asked by At

I am using Django-registration package. On that I have successfully implemented Django-reCAPTCHA package. CAPTCHA appears every time on login.

Now I want the CAPTCHA to appear only after 3 failed login attempts. How can I implement that?

Any help is appreciated. Thanks.

2

There are 2 answers

0
madzohan On

Store number of login attemplts in session https://docs.djangoproject.com/en/1.8/topics/http/sessions/ and use "django.contrib.sessions.backends.signed_cookies"

1
Addemark On

First store the number of failed login attempts in session in your login view: use this site to implement reCaptcha in django https://simpleisbetterthancomplex.com/tutorial/2017/02/21/how-to-add-recaptcha-to-django-site.html views.py

class UserLoginFormView(FormView):
   form_class = LoginForm
   success_url =  reverse_lazy('appuser:test')
   template_name = "appuser/login.html"

   def dispatch(self, request, *args, **kwargs):
       if ('lReq' in self.request.session):
          request.session['lReq'] +=1
       else:
          request.session['lReq'] = 1

      return super(UserLoginFormView,self).dispatch(request, *args, **kwargs)

in form valid make the decision based on the session value

def form_valid(self,form):
     if( self.request.session['lReq'] > 3):
      ..... your code to validate the captcha you will find in the site above... 

def render_to_response(self, context, **response_kwargs):
    if( self.request.session['lReq'] > 3):
       context['cap'] = True
    else:
       context['cap'] = False

    return super( UserLoginFormView,self).render_to_response(context,**response_kwargs)

In your template

    {% block content %}
  <form method="post">
    {% csrf_token %}
    {{ form.as_p }}
 {%if cap%}
<script src='https://www.google.com/recaptcha/api.js'></script>
<div class="g-recaptcha" data-sitekey="6LdRSRYUAAAAAFCqQ1aZnYfRGJIlAUMX3qkUWlcF"></div>
{%endif%}
<button type="submit" class="btn btn-primary">Post</button>

 {% endblock %}

This should work