带有 ColdFusion 的 reCaptcha v3
reCaptcha v3 with ColdFusion
我正在尝试将 reCaptcha (v3) 集成到 ColdFusion 站点。我对 CF 语法不太感兴趣,目前我似乎没有从服务器端的验证请求中得到任何回报。
任何人都可以看到任何明显错误的地方吗and/or 请指出正确的方向?
客户端:
<script src='https://www.google.com/recaptcha/api.js?render=6..."></script>
<script>
grecaptcha.ready(function() {
grecaptcha.execute('6...', {action: 'contact'})
.then(function(token) {
$("#recaptchaToken").val(token);
});
});
</script>
我的表单中有一个隐藏字段 recaptchaToken
,我可以看到其中的 token
值。
服务器端:
<cfhttp
url="https://www.google.com/recaptcha/api/siteverify"
method="POST"
result="captchaResponse">
<cfhttpparam
type="formfield"
name="secret"
value='6...'
/>
<cfhttpparam
type="formfield"
name="response"
value='#form.recaptchaToken#'
/>
</cfhttp>
<cfdump var=#captchaResponse.filecontent# />
我得到标题为 object of java.io.ByteArrayOutputStream
的红框输出
我试图转储 captchaResponse
和 captchaResponse.filecontent
都无济于事。
我期待以下形式的数据:
{
"success": true|false, // whether this request was a valid reCAPTCHA token for your site
"score": number // the score for this request (0.0 - 1.0)
"action": string // the action name for this request (important to verify)
"challenge_ts": timestamp, // timestamp of the challenge load (ISO format yyyy-MM-dd'T'HH:mm:ssZZ)
"hostname": string, // the hostname of the site where the reCAPTCHA was solved
"error-codes": [...] // optional
}
更新
解决方案似乎与亚历克斯在下面建议的一样:
<cfdump var=#toString(captchaResponse.filecontent)# />
这给了我预期格式的 JSON 字符串,因此我可以将其转换为 object 并完成验证。
每当 cfhttp
不确定如何处理响应时,原始内容将保持不变并保存为字节数组。这通常表示响应服务器未指定 Content-Type header 或内容仅部分检索。
要强制使用字符串表示内容,您可以使用 toString()
转换原始字节数组,例如toString(captchaResponse.filecontent)
。该函数非常健壮,还可以处理已经转换的字符串,因此通常可以安全使用。
不过,这里还有一点需要注意。当使用 cfhttp
而未将 throwOnError
属性设置为 true
(默认值为 false
)时,失败的 HTTP 请求仍然会 return 结果,残缺的结果.该结构将不包含 fileContent
键,因此会在运行时导致异常。您可能希望在此处添加错误处理,以防无法访问 https://www.google.com/recaptcha/api/siteverify
或您的 JRE 不支持接受的 TLS 协议。我们在 SNI 和 TLS 1.2 以及旧版本的 ColdFusion(即 8)中遇到了这个问题。请注意。
我正在尝试将 reCaptcha (v3) 集成到 ColdFusion 站点。我对 CF 语法不太感兴趣,目前我似乎没有从服务器端的验证请求中得到任何回报。
任何人都可以看到任何明显错误的地方吗and/or 请指出正确的方向?
客户端:
<script src='https://www.google.com/recaptcha/api.js?render=6..."></script>
<script>
grecaptcha.ready(function() {
grecaptcha.execute('6...', {action: 'contact'})
.then(function(token) {
$("#recaptchaToken").val(token);
});
});
</script>
我的表单中有一个隐藏字段 recaptchaToken
,我可以看到其中的 token
值。
服务器端:
<cfhttp
url="https://www.google.com/recaptcha/api/siteverify"
method="POST"
result="captchaResponse">
<cfhttpparam
type="formfield"
name="secret"
value='6...'
/>
<cfhttpparam
type="formfield"
name="response"
value='#form.recaptchaToken#'
/>
</cfhttp>
<cfdump var=#captchaResponse.filecontent# />
我得到标题为 object of java.io.ByteArrayOutputStream
我试图转储 captchaResponse
和 captchaResponse.filecontent
都无济于事。
我期待以下形式的数据:
{
"success": true|false, // whether this request was a valid reCAPTCHA token for your site
"score": number // the score for this request (0.0 - 1.0)
"action": string // the action name for this request (important to verify)
"challenge_ts": timestamp, // timestamp of the challenge load (ISO format yyyy-MM-dd'T'HH:mm:ssZZ)
"hostname": string, // the hostname of the site where the reCAPTCHA was solved
"error-codes": [...] // optional
}
更新
解决方案似乎与亚历克斯在下面建议的一样:
<cfdump var=#toString(captchaResponse.filecontent)# />
这给了我预期格式的 JSON 字符串,因此我可以将其转换为 object 并完成验证。
每当 cfhttp
不确定如何处理响应时,原始内容将保持不变并保存为字节数组。这通常表示响应服务器未指定 Content-Type header 或内容仅部分检索。
要强制使用字符串表示内容,您可以使用 toString()
转换原始字节数组,例如toString(captchaResponse.filecontent)
。该函数非常健壮,还可以处理已经转换的字符串,因此通常可以安全使用。
不过,这里还有一点需要注意。当使用 cfhttp
而未将 throwOnError
属性设置为 true
(默认值为 false
)时,失败的 HTTP 请求仍然会 return 结果,残缺的结果.该结构将不包含 fileContent
键,因此会在运行时导致异常。您可能希望在此处添加错误处理,以防无法访问 https://www.google.com/recaptcha/api/siteverify
或您的 JRE 不支持接受的 TLS 协议。我们在 SNI 和 TLS 1.2 以及旧版本的 ColdFusion(即 8)中遇到了这个问题。请注意。