1

Using Zope 2.13.29 and Python 2.7.15, I am trying to validate Google's reCaptcha2 using a Python script being called from a DTML document. The DTML document contains the form, and the same DTML document uses a dtml-if statement to determines whether to process the form once a user has clicked submit. Within that dtml-if statement is a dtml-in that calls to the python script in order to validate the reCaptcha and return the value of success (True or False). The issue is that I cannot seem to obtain the value of success.

While I know some of you may be inclined to talk about RestrictedPython and how I won't be able to import the python modules for use by Zope, that portion has already been taken care of. It all works, it just doesn't do what I need it to do.

This is the dtml-doc that shows the contact form, as well as determines whether submit has been clicked, which in turns calls to the python script to finally determine the returned value of the Google success variable from 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>

This is the python script (named 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}

When the script is run from the ZMI via the test tab, where I expect the result to be false, I get back

{'success': False}

However, I cannot seem to call on the success variable from the DTML-doc.

The form should be submitted, the python script should be run and validate the recaptcha, return the value of success (True/False) and then the dtml-if should decide how to proceed with processing the form.

4

2 回答 2

0

我不确定,但我认为您应该尝试创建一个 dtml-method,而不是 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

于 2019-02-19T11:07:35.747 回答
0

经过相当多的工作,并与许多不同的人交谈后,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-doc 的顶部,用于检查是否单击了提交并选择如何处理表单:

<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>

标签,并且只想更改主题,我尝试将主题:Web请求行与

<dtml-if recaptcha_validate>

陈述。那是行不通的。你必须有两个完全分开的

<dtml-sendmail>

节以使其正常工作。

于 2019-02-20T14:31:23.680 回答