Ответ На Ваш вопрос из реального проекта
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);
}
Вроде всё написал, удачи))