Created
October 30, 2019 17:25
-
-
Save maxpoletaev/293a55da714b736eb8f3fefce85f1b24 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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