Подтверждение reCaptcha2 с Zope2 - PullRequest
0 голосов
/ 13 февраля 2019

Используя Zope 2.13.29 и Python 2.7.15, я пытаюсь проверить Google reCaptcha2, используя скрипт Python, вызываемый из документа DTML.Документ DTML содержит форму, и тот же документ DTML использует инструкцию dtml-if, чтобы определить, следует ли обрабатывать форму после того, как пользователь нажал на кнопку submit.В этом выражении dtml-if есть dtml-вход, который вызывает скрипт python для проверки reCaptcha и возврата значения success (True или False).Проблема в том, что я не могу получить значение успеха.

Хотя я знаю, что некоторые из вас могут быть склонны говорить о RestrictedPython и о том, как я не смогу импортировать модули Python для использования ZopeОб этой части уже позаботились.Все работает, просто не делает то, что мне нужно.

Это dtml-документ, который отображает контактную форму, а также определяет, была ли нажата кнопка отправки, которая, в свою очередь, вызываетскрипт python для окончательного определения возвращаемого значения переменной успеха Google из reCaptcha.

<dtml-if submit>

<dtml-with recaptcha-validate>

<dtml-if expr="'success' == True">

<dtml-sendmail mailhost="MailHost">
To: info@foo.com
From: &dtml.lower-emailaddr;
Subject: Web Request

&dtml-message;

Sincerely,

&dtml-realname;
&dtml-emailaddr;
&dtml-phone;
&dtml-location;

</dtml-sendmail>

<dtml-else>

<dtml-sendmail mailhost="MailHost">
To: info@foo.com
From: &dtml.lower-emailaddr;
Subject: SPAM: Web Request

&dtml-message;

Sincerely,

&dtml-realname;
&dtml-emailaddr;
&dtml-phone;
&dtml-location;

</dtml-sendmail>

</dtml-if>
</dtml-with>

<dtml-else submit>

<dtml-var "foo.sitefiles.doctype(_.None, _)">
<html>
<head>
<title>Contact Us</title>

<script src="https://www.foo.com/javascript/jquery/jquery-min.js" type="text/javascript"></script>
<script src="https://www.foo.com/javascript/parsley/parsley.min.js" type="text/javascript"></script>

<script src="https://www.foo.com/javascript/misc/placeholder.js" type="text/javascript"></script>

<script src="https://www.google.com/recaptcha/api.js"></script>

</head>

<body>

<form data-parsley-validate id="contact-form" method="post" action=<dtml-var URL0> novalidate="" parsley-validate="" parsley-focus="none" data-parsley-errors-messages-disabled data-parsley-excluded="input[name=g-recaptcha-response], input[id=recaptcha-token]">
<fieldset>
<label>NAME</label>
<input class="parsley-validated" type="text" name="realname" placeholder="Enter your name" value="" required="">
<label>E-MAIL</label>
<input class="parsley-validated" type="email" name="emailaddr" placeholder="Enter your e-mail" value="" required="" pattern="^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$">
<label>PHONE NUMBER</label>
<input class="parsley-validated" type="text" name="phone" placeholder="Enter your contact phone number" value="" required="" pattern="^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$">
<label>LOCATION</label>
<input class="parsley-validated" type="text" name="location" placeholder="Enter your city, state" value="">
<label>MESSAGE</label>
<textarea class="parsley-validated" name="message" placeholder="Enter your message here" value="" required="" rows="8"></textarea>
<input id="myField" data-parsley-errors-container="#errorContainer" data-parsley-required="true" value="" type="text" style="display:none;">
<div id="contactrecaptcha">
<div id="recaptchatoken" class="g-recaptcha" data-sitekey="XXXXXXXXXX" data-        callback="recaptchaCallback"></div>
</div>
<span id='errorContainer'></span>
</fieldset>
<input type="submit" name="submit" value="SUBMIT">
</form>

<script type="text/javascript">
$('#contact-form').parsley();
function recaptchaCallback() {
    document.getElementById('myField').value = 'nonEmpty';
}
</script>

</body>
</html>

</dtml-if>

Это скрипт python (с именем recaptcha-validate):

import urllib
import urllib2
import json

REQUEST = container.REQUEST

URIReCaptcha = 'https://www.google.com/recaptcha/api/siteverify'
secret = 'XXXXXXXXXXXXXXXXXXX'
recaptcha_response = context.REQUEST['g-recaptcha-response']
remoteip = REQUEST.HTTP_X_FORWARDED_FOR

params = urllib.urlencode({
'secret': secret,
'response': recaptcha_response,
'remoteip': remoteip,
})

#print params
from urllib2 import urlopen
req = urllib2.Request(URIReCaptcha, params)
response = urllib2.urlopen(req)
result = json.load(response)
success = result.get('success', None)
return{'success': success}

Когда скрипт запускается из ZMI через тестовую вкладку, где я ожидаю, что результат будет ложным, я получаю обратно

{'success': False}

Однако я не могувызовите переменную success из DTML-документа.

Форма должна быть отправлена, скрипт python должен быть запущен и проверить recaptcha, вернуть значение success (True / False) и затем dtml-ifследует решить, как приступить к обработке формы.

Ответы [ 2 ]

0 голосов
/ 20 февраля 2019

После долгой работы и общения с разными людьми, очень добрый человек на форумах Plone показал мне, что я делаю неправильно.Я делал это слишком сложно, но было очень близко.

Вот скрипт на python (названный recaptcha_validate):

import urllib
import urllib2
import json

REQUEST = container.REQUEST

URIReCaptcha = 'https://www.google.com/recaptcha/api/siteverify'
secret = 'XXXXXXXXXXX'
recaptcha_response = context.REQUEST['g-recaptcha-response']
remoteip = REQUEST.HTTP_X_FORWARDED_FOR

params = urllib.urlencode({
'secret': secret,
'response': recaptcha_response,
'remoteip': remoteip,
})

#print params
from urllib2 import urlopen
req = urllib2.Request(URIReCaptcha, params)
response = urllib2.urlopen(req)
result = json.load(response)
success = result.get('success', None)
return success

Вот верхняя часть dtml-документа, которая проверяет, была ли отправкащелкнул и выбирает способ обработки формы:

<dtml-if submit>

<dtml-if recaptcha_validate>

<dtml-sendmail mailhost="MailHost">
To: info@foo.com
From: &dtml.lower-emailaddr;
Subject: Web Request

&dtml-message;

Sincerely,

&dtml-realname;
&dtml-emailaddr;
&dtml-phone;
&dtml-location;

</dtml-sendmail>

<dtml-else>

<dtml-sendmail mailhost="MailHost">
To: info@foo.com
From: &dtml.lower-emailaddr;
Subject: SPAM: Web Request

&dtml-message;

Sincerely,

&dtml-realname;
&dtml-emailaddr;
&dtml-phone;
&dtml-location;

</dtml-sendmail>

</dtml-if>

Выполнение простого

<dtml-if recaptcha_validate>

запускает скрипт python и проверяет, является ли результат верным.Не нужно никаких переменных или выражений в этом случае.Это действительно так просто.

Примечание. Используя тег

<dtml-sendmail>

и только желая сменить тему, я попытался окружить строку Subject: Web Request строкой

<dtml-if recaptcha_validate>

заявление.Это не работает.У вас должно быть два совершенно отдельных

<dtml-sendmail>

строфа, чтобы это работало правильно.

0 голосов
/ 19 февраля 2019

Я не уверен, но я думаю, что вы должны попытаться создать dtml-метод вместо dtml-doc.

https://zope.readthedocs.io/en/latest/zope2book/DTML.html#formatting-and-displaying-sequences

Вам также следует рассмотреть возможность использования ZPT вместоDTML.

Обратите внимание на первое примечание: https://zope.readthedocs.io/en/latest/zope2book/DTML.html#basic-dtml

...