@Saipy

Как подключить Yandex Smart Captcha на сайт Django?

Как подключить Yandex SmartCapthca в форму регистрации Django, так как Гугл Капча заблокирована в России на данный момент. Или может есть какая нибудь нормальная полная документация по подключению данной капчи? На официальном сайте инструкция неполная и непонятная, а в поддержке отказались помогать со словами что не имеют нужной квалификации чтобы помочь настроить свой же продукт
  • Вопрос задан
  • 420 просмотров
Решения вопроса 1
sergey_1990
@sergey_1990
1
Ответ На Ваш вопрос из реального проекта
views.py
def get_client_ip(request):
    """получение IP пользователя"""
    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 check_captcha(token,request):
    """проверка токена капчи"""
    guest_ip = str(get_client_ip(request))
    resp = requests.get(
        "https://captcha-api.yandex.ru/validate",
        {
            "secret": settings.YACAPCHA_SERVER,
            "token": token,
            "ip": guest_ip  # Нужно передать IP пользователя.
                               # Как правильно получить IP зависит от вашего фреймворка и прокси.
                               # Например, в Flask это может быть request.remote_addr
        },
        timeout=1
    )
    server_output = resp.content.decode()
    if resp.status_code != 200:
        print(f"Allow access due to an error: code={resp.status_code}; message={server_output}", file=sys.stderr)
        return True
    return json.loads(server_output)["status"] == "ok"

class RequestWithCapchaCreateAPI(generics.CreateAPIView):
    """общий класс для проверки каппчи"""
    def create(self, request, *args, **kwargs):
        captchaToken = request.POST['smart-token']
        if check_captcha(captchaToken,request):
            return super().create(request, *args, **kwargs)
        else:
            return  JsonResponse({'status':'false','message':'ROBOT'}, status=423)

    def perform_create(self, serializer):
        subdomain = get_subdomain(self.request)
        serializer.save(subdomain=subdomain)

class CallRequestCreateAPI(RequestWithCapchaCreateAPI):
    """создание запроса на звонок"""
    serializer_class = CallRequestSerializer

settings.py
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR/ 'templates'], # add for index (templates),
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
                'wellway_system.context_processors.debug',
                'wellway_system.context_processors.capcha', #Капчу в общий контекст
            ],
        },
    },
]
# Для yandex capcha
SECURE_REFERRER_POLICY = 'no-referrer-when-downgrade'
YACAPCHA_CLIENT = '...........' #Ключ клиента
YACAPCHA_SERVER = '...........' #Ключ сервера

context_processors.py
from django.conf import settings

def capcha(context):
  return {'YACAPCHA_CLIENT': settings.YACAPCHA_CLIENT}


В шаблоне в подключаем
<script src="https://captcha-api.yandex.ru/captcha.js?render=onload&onload=onloadFunction" defer></script>

В шаблоне в конце подключаем
<script>
		function onloadFunction() {
		  if (window.smartCaptcha) {
			const containers = document.querySelectorAll('#captcha-container');
			containers.forEach(function (container) {
			  const widgetId = window.smartCaptcha.render(container, {
				sitekey: "{{ YACAPCHA_CLIENT }}",
			  });
			  container.dataset.widgetid = widgetId
			})
		  }
		}
	  </script>

в форму включаем
<div style="height: 100px" id="captcha-container" class="smart-captcha"></div>

ну и в скриптах везде по-разному но смысл один делаем ресет кода капчи например
function formSent(form, responseResult = ``) {
            document.dispatchEvent(new CustomEvent("formSent", {
                detail: {
                    form
                }
            }));
            setTimeout((() => {
                if (flsModules.popup) {
                    const popup = form.dataset.popupMessage;
                    popup ? flsModules.popup.open(popup) : null;
                }
            }), 0);
            formValidate.formClean(form);
            formLogging(`Форма отправлена!`);
            let widget = form.querySelector("#captcha-container");
            let widgetId = widget.dataset.widgetid;
            smartCaptchaReset(widgetId);
        }

Вроде всё написал, удачи))
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@maksam07
У капчи есть апи документация с примерами для питона. Что именно вам непонятно? Если вы у поддержки спрашивали, как подключить ее в джанго, то они и не обязаны отвечать, у них на сайте информации более чем достаточно, чтобы подключить их капчу.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы