Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Including captcha in a django form

I'm trying to add Captcha to my Django form. I tried three different libraries but none of them worked for me and i don't know what i'm doing wrong. Here is my last try:

I used this library. My forms.py looks like this:

class NewUserForm(UserCreationForm):
    email = forms.EmailField(required=True)
    captcha = NoReCaptchaField()

    class Meta:
        model = User
        fields = ("username", "email", "password1", "password2")

    def save(self, commit=True):
        user = super(NewUserForm, self).save(commit=False)
        user.email = self.cleaned_data['email']
        if commit:
            user.save()
        return user

This is urls.py: path("login/", views.login_request, name="login").

This is the frontend: login.html: <script src="https://www.google.com/recaptcha/api.js" async defer></script>

I updated my settings.py file, so the error must not be there.

like image 302
Dev012 Avatar asked Feb 26 '19 15:02

Dev012


2 Answers

You can use django-simple-captcha.

  1. Install it
pip install  django-simple-captcha
  1. Add captcha to the INSTALLED_APPS in your settings.py
  2. Run python manage.py migrate
  3. Add an entry to your urls.py:
urlpatterns += [
       path(r'captcha/', include('captcha.urls')),
    ]

in forms.py:

from django import forms
from captcha.fields import CaptchaField
    
class YourForm(forms.Form):
    captcha = CaptchaField()

in template:

<form action="/your-name/" method="post">
   {% csrf_token %}
   {{ form.captcha }}
   <input type="submit" value="Submit">
</form>
like image 106
rahul.m Avatar answered Oct 03 '22 01:10

rahul.m


You can also use a mixin

Have your views inherit from a mixin that validates a recaptcha, c.greys solution is probably easier tbh but you may want to do other things with the request outside the template.

import requests
from django.http.response import HttpResponseForbidden
from ipware import get_client_ip

from .settings import RECAPTCHA_KEY, RECAPTCHA_SECRET


class GoogleRecaptchaMixin:
    def post(self, request, *args, **kwargs):
        g_recaptcha_response = request.POST.get('g-recaptcha-response', None)
        client_ip, is_routable = get_client_ip(request)
        response = requests.post(
            "https://www.google.com/recaptcha/api/siteverify",
            data={
                "secret": RECAPTCHA_SECRET,
                "response": g_recaptcha_response,
                "remoteip": client_ip
            }
        )
        response_dict = response.json()
        if response_dict.get("success", None):
            return super().post(request, *args, **kwargs)
        else:
            return HttpResponseForbidden(*args, **kwargs)

In the same directory as the code above you would have a settings file with your key and secret or you could directly import from django.conf

#settings.py
from django.conf import settings


RECAPTCHA_SECRET = getattr(settings, "RECAPTCHA_SECRET", '')
RECAPTCHA_KEY = getattr(settings, "RECAPTCHA_KEY", '')

In your template you would have something like:

<form id="form-00" method="post" action="/process">{% csrf_token %}
  <button class="g-recaptcha"
          data-sitekey="your recaptcha key"
          data-callback="formSubmit">Recaptcha this</button>
</form>
<script type="text/javascript" src='https://www.google.com/recaptcha/api.js'></script>
<script type="text/javascript">
        function formSubmit(token) {
            document.getElementById("form-00").submit();
        }
</script>
like image 24
bob Avatar answered Oct 03 '22 00:10

bob