How to validate Google reCAPTCHA v2 in django

醉酒当歌 提交于 2020-01-12 05:24:09

问题


I have been trying to use the Google reCAPTCHA on a website that I've been making. The captcha loads on the webpage but I've been unable to validate it using several methods. I've tried the recaptcha validation using the method given at How to use Python plugin reCaptcha client for validation? but I think it's outdated as it no longer works and it is referring to challenges whereas the one I'm trying to use is the new 'checkbox' reCAPTCHA v2 by Google or maybe I need to make changes in my settings after installing recaptcha-client or django-recaptcha.

Please help!


回答1:


There is a third-party Django app to implement the new reCAPTCHA v2 here:

https://github.com/ImaginaryLandscape/django-nocaptcha-recaptcha

After installing it, add the following lines to the following files:

# settings.py
NORECAPTCHA_SITE_KEY = <the Google provided site_key>
NORECAPTCHA_SECRET_KEY = <the Google provided secret_key>

INSTALLED_APPS = (
    ....
    'nocaptcha_recaptcha'
)


#forms.py
from nocaptcha_recaptcha.fields import NoReCaptchaField

class YourForm(forms.Form):
    .....
    captcha = NoReCaptchaField()


# In your template, add the following script tag:
<script src="https://www.google.com/recaptcha/api.js" async defer></script>



回答2:


Here is a simple example to verify Google reCAPTCHA v2 within Django view using requests library (http://docs.python-requests.org/en/latest/):

import requests
from django.conf import settings

def get_client_ip(request):
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        ip = x_forwarded_for.split(',')[0]
    else:
        ip = request.META.get('REMOTE_ADDR')
    return ip

def grecaptcha_verify(request):
    if request.method == 'POST':
        response = {}
        data = request.POST
        captcha_rs = data.get('g-recaptcha-response')
        url = "https://www.google.com/recaptcha/api/siteverify"
        params = {
            'secret': settings.RECAPTCHA_SECRET_KEY,
            'response': captcha_rs,
            'remoteip': get_client_ip(request)
        }
        verify_rs = requests.get(url, params=params, verify=True)
        verify_rs = verify_rs.json()
        response["status"] = verify_rs.get("success", False)
        response['message'] = verify_rs.get('error-codes', None) or "Unspecified error."
        return HttpResponse(response)



回答3:


Google has changed the API around, we need to use a POST request now. Here a re-usable solution in case you need to do the validation in more than one django view:

utils.py

# django imports
from django.conf import settings
from django.views.generic.base import View
from django.http import HttpResponseForbidden

# 3rd-party imports
import requests
from ipware import get_client_ip


def is_recaptcha_valid(request):
    """
    Verify if the response for the Google recaptcha is valid.
    """
    return requests.post(
        settings.GOOGLE_VERIFY_RECAPTCHA_URL,
        data={
            'secret': settings.RECAPTCHA_SECRET_KEY,
            'response': request.POST.get('g-recaptcha-response'),
            'remoteip': get_client_ip(request)
        },
        verify=True
    ).json().get("success", False)



def human_required(view_func):
    """
    This decorator is aimed to verify Google recaptcha in the backend side.
    """
    def wrapped(request, *args, **kwargs):
        if is_recaptcha_valid(request):
            return view_func(request, *args, **kwargs)
        else:
            return HttpResponseForbidden()
    return wrapped

then:

views.py

 from utils import human_required

 class MyView(View):

     @human_required
     def post(request, *args, **args):
        pass

Note we are using django-ipware in this solution to get the ip address, but this is up to you. Also, don't forget to add GOOGLE_VERIFY_RECAPTCHA_URL and RECAPTCHA_SECRET_KEY to the django settings file!




回答4:


views.py

def login(request):
    if request.method == 'POST':
    username = request.POST['username']
    password = request.POST['password']
    user = auth.authenticate(request, username=username, password=password)

     if user is not None:
        if user.is_active:
            auth.login(request, user)
            ''' Begin reCAPTCHA validation '''
            recaptcha_response = request.POST.get('g-recaptcha-response')
            url = 'https://www.google.com/recaptcha/api/siteverify'
            values = {
            'secret' : settings.GOOGLE_RECAPTCHA_SECRET_KEY,
            'response' :  recaptcha_response
            }
            data = urllib.parse.urlencode(values).encode("utf-8")
            req = urllib2.Request(url, data)
            response = urllib2.urlopen(req)
            result = json.load(response)
            ''' End reCAPTCHA validation '''

            if result['success']:
              return redirect('index')
            else:
              messages.error(request, 'Invalid reCAPTCHA. Please try again.')
              return redirect('login')
    else:
        messages.info(request, 'Wrong Credentials!!! enter right username or password')
        return redirect('login')
else:
    return render(request, 'login.html')

login.html

<form action="{% url 'login' %}" method="post">
            {% csrf_token %}
            <div class="body bg-gray">
                <div class="form-group">
                    <input type="text" name="username" class="form-control" placeholder="Username"/>
                </div>
                <div class="form-group">
                    <input type="password" name="password" class="form-control" placeholder="Password"/>
                </div>          
                <div class="form-group">
                    <input type="checkbox" name="remember_me"/> Remember me
                </div>
            </div>
            <div class="footer">                                                               
                 <button type="submit" class="btn bg-olive btn-block">Sign me in</button>

                <p><a href="#">I forgot my password</a></p>

                <a href="{% url 'register' %}" class="text-center">Register a new membership</a>
            </div>
            <br><br>
            <script src='https://www.google.com/recaptcha/api.js'></script>
            <div class="g-recaptcha" data-sitekey="(enter your key here that is private or authenticated on google recapthcha)"></div>
        </form>

settings.py

INSTALLED_APPS = [
   ....
   ....
   'captcha'
               ]

GOOGLE_RECAPTCHA_SECRET_KEY ='6LdXBLAUAMlGYqqyDESeHKI7-'
RECAPTCHA_PUBLIC_KEY = '6LdXBLAUAAAAAP3oI1VPJgA-VHXoj'
RECAPTCHA_PRIVATE_KEY = '6LdXBLAUAAAAAGYqqyDESeHKI7-'

''' you have to register your domain to get the access of these keys. or you can 
register your localhost also to test this after uploading on the server you can 
register with real domain and change the keys.

don't forget to like if you find it helpful.'''

 'https://www.google.com/recaptcha/intro/v3.html' -> 'admin console' where you can 
 register your domain or localhost and get your key. 


来源:https://stackoverflow.com/questions/29548574/how-to-validate-google-recaptcha-v2-in-django

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!