使用Zope 2.13.29和Python 2.7.15,我试图使用从DTML文档调用的Python脚本来验证Google的reCaptcha2。 DTML文档包含表单,并且相同的DTML文档使用dtml-if语句来确定在用户单击提交后是否处理表单。在该dtml-if语句中是一个dtml-in,它调用python脚本以验证reCaptcha并返回success的值(True或False)。问题是我似乎无法获得成功的价值。
虽然我知道你们中的一些人可能倾向于谈论RestrictedPython以及我如何无法导入供Zope使用的python模块,但这部分已经得到了解决。一切正常,它只是没有做我需要它做的事情。
这是显示联系表单的dtml-doc,并确定是否已单击提交,然后调用python脚本以最终确定从reCaptcha返回的Google成功变量值。
<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运行时,我希望结果为假,我回来了
{'成功':错误}
但是,我似乎无法调用DTML-doc中的成功变量。
应该提交表单,运行python脚本并验证recaptcha,返回成功的值(True / False),然后dtml-if应该决定如何继续处理表单。
我不确定,但我认为你应该尝试创建一个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
经过相当多的工作,并与许多不同的人交谈,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脚本并检查结果是否为true。在这种情况下不需要任何变量或表达式。这真的很简单。
注意:使用
<dtml-sendmail>
标签,只想更改主题,我尝试围绕主题:Web请求行与
<dtml-if recaptcha_validate>
声明。这不起作用。你必须有两个完全分开的
<dtml-sendmail>
节,以便正常工作。