我一直在尝试在我一直在制作的网站上使用Google reCAPTCHA。验证码加载在网页上,但我无法使用多种方法验证它。我已经尝试使用给出的方法进行重新验证 How to use Python plugin reCaptcha client for validation?但我觉得它已经过时,因为它不再有效,它指的是挑战,而我正在尝试使用的是Google的新“复选框”reCAPTCHA v2,或者我需要在设置中进行更改安装recaptcha-client或django-recaptcha之后。
请帮忙!
答案 0 :(得分:26)
以下是使用requests
库(http://docs.python-requests.org/en/latest/)在Django视图中验证Google reCAPTCHA v2的简单示例:
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)
答案 1 :(得分:9)
有一个第三方Django应用程序在这里实现新的reCAPTCHA v2:
https://github.com/ImaginaryLandscape/django-nocaptcha-recaptcha
安装后,将以下行添加到以下文件中:
# 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 :(得分:6)
Google已更改了API,我们现在需要使用 POST 请求。这是一个可重复使用的解决方案,以防您需要在多个django视图中进行验证:
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
然后:
views.py
from utils import human_required
class MyView(View):
@human_required
def post(request, *args, **args):
pass
请注意,我们在此解决方案中使用django-ipware来获取IP地址,但这取决于您。另外,不要忘记将GOOGLE_VERIFY_RECAPTCHA_URL
和RECAPTCHA_SECRET_KEY
添加到django设置文件中!
答案 3 :(得分:1)
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')
<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>
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.
答案 4 :(得分:0)
扩展@trinchet给出的答案,这里是FormView Django类的简单修改,以自动处理Google的reCAPTCHA v2。
class RecaptchaFormView(FormView):
""" This class handles Google's reCAPTCHA v2. """
recaptcha_ok = None
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['grecaptcha_site_key'] = settings.RECAPTCHA_SITE_KEY
return context
def get_form(self):
form = super().get_form()
if self.recaptcha_ok == False:
form.add_error(None, "Invalid reCAPTCHA, please try again.")
return form
def post(self, request, *args, **kwargs):
self.recaptcha_ok = is_recaptcha_valid(request)
return super().post(self, request, *args, **kwargs)
请不要忘记在@trinchet中提供is_recaptcha_valid函数(请参见他的答案),在settings.py中包含reCAPTCHA键,并在模板中包含reCAPTCHA代码(使用{{ grecaptcha_site_key }}
作为站点键)。>
答案 5 :(得分:0)
这就是我处理提议问题的方式:
from django.contrib.auth.views import LoginView, LogoutView
from django.conf import settings
from authentication.forms import MyAuthenticationForm
class MyLoginView(LoginView):
template_name = 'authentication/login.html'
form_class = MyAuthenticationForm
def get_client_ip(self):
x_forwarded_for = self.request.META.get('HTTP_X_FORWARDED_FOR')
if x_forwarded_for:
ip = x_forwarded_for.split(',')[0]
else:
ip = self.request.META.get('REMOTE_ADDR')
return ip
def get_form_kwargs(self):
kwargs = super(MyLoginView, self).get_form_kwargs()
if self.request.method in 'POST':
kwargs['g-recaptcha-response'] = self.request.POST.get('g-recaptcha-response')
kwargs['remote_ip'] = self.get_client_ip()
return kwargs
def get_context_data(self, **kwargs):
context = super(MyLoginView, self).get_context_data(**kwargs)
# To use in the template
context['recaptcha_challenge_secret'] = settings.G_RECAPTCHA_CHALLENGE_SECRET
return context
import requests
from django.contrib.auth.forms import AuthenticationForm
from django.conf import settings
from django.forms import ValidationError
from django.utils.translation import ugettext_lazy as _
class MyAuthenticationForm(AuthenticationForm):
def __init__(self, *args, **kwargs):
self.g_recaptcha_response = kwargs.pop('g-recaptcha-response', None)
self.remote_ip = kwargs.pop('remote_ip', None)
super(MyAuthenticationForm, self).__init__(*args, **kwargs)
def clean(self):
cleaned_data = super(MyAuthenticationForm, self).clean()
self.verify_captcha()
return cleaned_data
def verify_captcha(self):
if self.g_recaptcha_response:
data = {
'secret': settings.G_RECAPTCHA_VERIFY_SECRET,
'response': self.g_recaptcha_response,
'remoteip': self.remote_ip
}
response = requests.post(settings.G_RECAPTCHA_VERIFICATION_URL, data=data)
result = response.json()
if result['success']:
return
raise ValidationError(
_('Invalid reCAPTCHA challenge.'),
code='invalid_recaptcha_challenge'
)