首先我们需要认识到什么是reCAPTCHA
reCAPTCHA 验证”机制可以提供保护,避免发生由机器人导致的垃圾邮件或滥用。 通过此机制,将向用户显示一个Web 页面,其中包含Google reCAPTCHA API 提供的简单调整测试。 这些测试可以区分实际用户和机器人。 您可以将此机制添加到策略,以阻止机器人访问应用程序。
由于谷歌验证需要使用谷歌服务器,可能无法访问,需要使用另一个域名来实现客户端的访问。因为recaptcha是通过js导入的,是客户端层面的。
不过本人还是比较喜欢把js代码放在本地,这样能节省一些从远程web服务器下载js文件的时间。
中文版的js文件
/* PLEASE DO NOT COPY AND PASTE THIS CODE. */
(function() {
var w = window,
C = '___grecaptcha_cfg',
cfg = w[C] = w[C] || {},
N = 'grecaptcha';
var gr = w[N] = w[N] || {};
gr.ready = gr.ready ||
function(f) { (cfg['fns'] = cfg['fns'] || []).push(f);
};
w['__recaptcha_api'] = 'https://recaptcha.net/recaptcha/api2/'; (cfg['render'] = cfg['render'] || []).push('onload');
w['__google_recaptcha_client'] = true;
var d = document,
po = d.createElement('script');
po.type = 'text/javascript';
po.async = true;
po.src = 'https://www.gstatic.com/recaptcha/releases/TDBxTlSsKAUm3tSIa0fwIqNu/recaptcha__zh_cn.js';
po.crossOrigin = 'anonymous';
po.integrity = 'sha384-+1xTZD1vXy4iYpvAgshm/J25tGGIOEBGzwJvtWiX6bJvTIuQBQI0VJIeRASsTPiz';
var e = d.querySelector('script[nonce]'),
n = e && (e['nonce'] || e.getAttribute('nonce'));
if (n) {
po.setAttribute('nonce', n);
}
var s = d.getElementsByTagName('script')[0];
s.parentNode.insertBefore(po, s);
})();
英文版的js文件
/* PLEASE DO NOT COPY AND PASTE THIS CODE. */
(function() {
var w = window,
C = '___grecaptcha_cfg',
cfg = w[C] = w[C] || {},
N = 'grecaptcha';
var gr = w[N] = w[N] || {};
gr.ready = gr.ready ||
function(f) { (cfg['fns'] = cfg['fns'] || []).push(f);
};
w['__recaptcha_api'] = 'https://recaptcha.net/recaptcha/api2/'; (cfg['render'] = cfg['render'] || []).push('onload');
w['__google_recaptcha_client'] = true;
var d = document,
po = d.createElement('script');
po.type = 'text/javascript';
po.async = true;
po.src = 'https://www.gstatic.com/recaptcha/releases/dPctOHA2ifhWm5WzFM_B5TjT/recaptcha__en.js';
po.crossOrigin = 'anonymous';
po.integrity = 'sha384-YOM1VjUkAnOtLKpWHvk6KSrYAoLEkaoPuep5VFiDATRna5swsN03dxDH51fiq3/H';
var e = d.querySelector('script[nonce]'),
n = e && (e['nonce'] || e.getAttribute('nonce'));
if (n) {
po.setAttribute('nonce', n);
}
var s = d.getElementsByTagName('script')[0];
s.parentNode.insertBefore(po, s);
})();
在html页面通过script标签导入外部js文件后,就可以在form表单中插入如代码块。
我们需要在g-recaptcha中的data-sitekey中设置谷歌分配给我们的公钥,也就是我们需要发送到客户端的公钥。
<div class="g-recaptcha" data-sitekey="public_key"></div>
在php后端,我们需要对用户传入的g-recaptcha参数进行判断。
if (!empty($_POST['g-recaptcha-response'])){
$g_v_response = $_POST['g-recaptcha-response'];
$google_verify_result = json_decode(verify_code($google_verify_private_key,$g_v_response),true);
if($google_verify_result['success'] == 1){
#谷歌验证成功
}else{
#谷歌验证失败
}
}
而这仅仅是针对谷歌验证的大致判断逻辑,对于verify_code的验证函数如下:
function verify_code($private_key,$user_key)
{
$target_url = "https://recaptcha.net/recaptcha/api/siteverify";
$post_data = array();
$post_data['secret'] = $private_key;
$post_data['response'] = $user_key;
$response = send_post($target_url,$post_data);
return $response;
}
function send_post( $url , $post_data ) {
$postdata = http_build_query( $post_data );
$options = array (
'http' => array (
'method' => 'POST' ,
'header' => 'Content-type:application/x-www-form-urlencoded' ,
'content' => $postdata ,
'timeout' => 15 * 60
)
);
$context = stream_context_create( $options );
$result = file_get_contents( $url , false, $context );
return $result ;
}
在这里,private_key为谷歌验证平台为我们提供的私钥,而$user_key就是用户点击了谷歌验证之后,后台收到的g-recaptcha的参数。
并没有使用www.google.com因为在连接过程中可能有一些问题。
同时我们像目标url发送post请求的方法也如上。不过超时时间最好根据项目需要动态变更。
而如果对谷歌验证的接入文档有独立开发需要的,可以参考文档