Skip to content

Instantly share code, notes, and snippets.

@maxpoletaev
Created October 30, 2019 17:25
Show Gist options
  • Save maxpoletaev/293a55da714b736eb8f3fefce85f1b24 to your computer and use it in GitHub Desktop.
Save maxpoletaev/293a55da714b736eb8f3fefce85f1b24 to your computer and use it in GitHub Desktop.
import requests
from django.conf import settings
from rest_framework import serializers
from .request import get_client_ip
def verify_recaptcha(recaptcha_response, *, remote_ip=None,
secret_key=settings.RECAPTCHA_SECRET_KEY):
if settings.RECAPTCHA_WILD_CODE and \
recaptcha_response == settings.RECAPTCHA_WILD_CODE:
return True
data = {
'response': recaptcha_response,
'secret': secret_key,
}
if remote_ip is not None:
data['remote_ip'] = remote_ip
response = requests.post(
'https://www.google.com/recaptcha/api/siteverify',
timeout=(3, 5), # connection, read
data=data,
)
response.raise_for_status()
data = response.json()
return data['success']
class RecaptchaValidator:
message = 'Invalid verification code.'
def __init__(self):
self.parent = None
def set_context(self, parent):
self.parent = parent
def get_remote_ip(self):
if self.parent is not None:
request = self.parent.context.get('request')
if request is not None:
return get_client_ip(request)
def __call__(self, value):
remote_ip = self.get_remote_ip()
if not verify_recaptcha(value, remote_ip=remote_ip):
raise serializers.ValidationError(self.message, code='invalid')
return value
class RecaptchaSerializerMixin:
def __init__(self: serializers.Serializer, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['g-recaptcha-response'] = serializers.CharField(
source='g_recaptcha_response',
validators=[RecaptchaValidator()],
required=True,
write_only=True,
)
def validate(self, validated_data):
validated_data.pop('g_recaptcha_response', None)
super().validate(validated_data)
return validated_data
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment