谷歌 google验证码 reCAPTCHA V3 对接

6,047 阅读2分钟

官方文档:developers.google.com/recaptcha/i…
管理后台:www.google.com/recaptcha/a…

注册新网站

image.png

注册成功后,得到密钥

image.png

2个密钥,一个是在客户端使用,一个是在服务端使用

前端

  • 官方的demo
<script src="https://www.recaptcha.net/recaptcha/api.js?render=_reCAPTCHA_site_key_"></script>
<script>
  grecaptcha.ready(function () {
    grecaptcha.execute('_reCAPTCHA_site_key_', { action: 'homepage' }).then(function (token) {
      console.log(token)
    });
  });
</script>
# _reCAPTCHA_site_key_ 就是客户的的密钥

核心代码就是通过执行 grecaptcha.execute(...) 方法,在回调中获取到 token值。

v3它没有显式的一个操作,他可以在用户不知道的情况下进行验证,通过判断用户评分这些,不过评分判断要配合后端使用,如果是纯前端操作,那么会和v2一样,成功会返回一个token。

action参数为验证场景,可以自己定义名称,作用就是可以在后台,对于不同的场景进行特别的设置。例如专门为登录设计一个场景: login。

谷歌提供了4种场景,可以自行根据使用场景的不同替换参数。

  • action |参数|使用场景| |---|---| |homepage|一般场景,可在管理后台查看流量趋势| |login|分数较低的用户需要进行二次验证| |social|限制一些滥用的用户请求,一般用于评论| |e-commerce|商品交易的时候|

后端的验证

POST 参数描述
secret必须的,服务端的密钥
response必须的,客户端验证的Token
remoteip可选的,客户端的ip地址
  • 响应
    • 1、成功
    {
      score: 0.9  // 评分0 到 1。1:确认为人类,0:确认为机器人。
      hostname: "localhost"  // 请求的地址
      success: true  // 是否验证成功,
      challenge_ts: "2020-02-27T05:26:05Z"
      action: "homepage"
    }
    # 系统可以根据 score 值来判定此次请求是否合法。
    
    • 2、失败
    {
      "success": true|false,
      "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
    }
    
  • error-codes |error-codes|说明| |---|---| |missing-input-secret|缺少输入密钥,也就是key没有| |invalid-input-secret|secret参数无效或者不正确| |missing-input-response|response参数没有,也就是token不存在| |invalid-input-response|response参数无效或者不正确| |bad-request|请求无效或格式不正确|

国内的用户需要替换js文件的地址和服务端验证接口的地址:
1、替换客户端js地址
www.google.com/recaptcha/a… 替换为 www.recaptcha.net/recaptcha/a… 2、替换服务端接口地址
www.google.com/recaptcha/a… 替换为www.recaptcha.net/recaptcha/a…

完整案例

客户端

<script src="https://recaptcha.net/recaptcha/api.js?render=_reCAPTCHA_site_key_"></script>
<script>
    grecaptcha.ready(function () {
        var act = 'downdetail';
            grecaptcha.execute('_reCAPTCHA_site_key_', {
                action: act
            }).then(function (token) {
                window.v3token = token;
                # 业务逻辑代码,须将token传递后端进行验证
            });
    });
</script>

服务端

function checkvali($response){
    $post_data = array(
        'secret'=>'自己的密钥',
        'response'=>$response
    );
    $recaptcha_json_result = send_post('https://recaptcha.net/recaptcha/api/siteverify', $post_data);
    $recaptcha_result = json_decode($recaptcha_json_result,true);
    return $recaptcha_result;
}

function send_post($url, $post_data)
{
    $postdata = http_build_query($post_data);
    $options = array(
        'ssl' => [
            'verify_peer' => false,
            'verify_peer_name' => false,
        ],
        'http' => array(
            'method' => 'POST',
            'header' => 'Content-type:application/x-www-form-urlencoded',
            'content' => $postdata,
            'timeout' => 15 * 60 // 超时时间(单位:s)
        )
    );
    $context = stream_context_create($options);
    $result = file_get_contents($url, false, $context);
    return $result;
}
checkvali($response);
# 调用checkvali方法后,根据返回的结果再写业务逻辑
# $response 就是客户端传递过来的 token

隐藏ReCAPTCHA图标

使用 reCAPTCHA,会在网站上提示出一个图标.。

image.png

如果需要隐藏,可以添加css

.grecaptcha-badge { 
	display: none; 
}