GX博客

分享个人 Full-Stack JavaScript 项目开发经验

使用reCAPTCHA第2版“进行人机身份验证”复选框的应用例子

本文介绍 Google 的 reCAPTCHA v2 中的“进行人机身份验证”复选框的应用例子。


注册网站信息

首先,我们需要使用谷歌账号登录 https://www.google.com/recaptcha/admin,填写网站域名和标签相关信息。然后在 reCAPTCHA 类型中选择“进行人机身份验证”复选框。最后谷歌会为你生成两个密钥。一个是你的网站提供给用户的 HTML 代码中使用的网站密钥,另一个为你的网站服务器端和 reCAPTCHA 之间的通信密钥。


客户端的设置

html

<form>
    <div id="recaptcha" class="g-recaptcha"></div>
    <button id="signIn" class="btn btn-lg btn-default btn-block" disabled type="button">登录</button>
</form>

<script src="/index.js"></script>
<script src="https://www.recaptcha.net/recaptcha/api.js?onload=onloadCallback&render=explicit"></script>

这里选择显式渲染 reCAPTCHA,以便可以控制在登录失败一次后再要求用户证明自己不是机器人。

表单中使用固定类名 g-recaptcha 的 div 作为 reCAPTCHA 的渲染容器。最后一个 script 标签加载 reCAPTCHA 的相关脚本。其中参数 onload 用于定义加载完毕时调用的函数名称,这里的 onloadCallback 回调函数放在更先加载 index.js 中。参数 render 值为 explicit 代表要求显式地渲染,而不是 onload 时找到 g-recaptcha 标签然后渲染。

index.js

var widgetId;

function onloadCallback() {
    // 显式渲染 reCAPTCHA
    widgetId = grecaptcha.render('recaptcha', {sitekey: 'your_sitekey'});

    $('#signIn').prop('disabled', false);
}

function submit(){
    // 获取响应结果,需要把结果发送给后台
    var recaptcha = grecaptcha.getResponse(widgetId);
    ......
    // 后台验证失败时,重置 reCAPTCHA
    grecaptcha.reset(widgetId);
}

服务器端验证结果

在服务器端接收客户端的 reCAPTCHA 响应,并请求验证结果。下面以 koa2 作为服务器端框架,介绍这个过程:

const https = require("https");
const querystring = require('querystring');

module.exports = async (ctx, next) => {
    // ......
    const {recaptcha} = ctx.request.body;

    // reCAPTCHA 认证
    const verifyCaptcha = function () {

        return new Promise((resolve, reject) => {

            const verify_data = querystring.stringify({
                secret: 'your_secret',
                response: recaptcha
            });

            const post_req = https.request({
                host: 'recaptcha.net',
                path: '/recaptcha/api/siteverify',
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                    'Content-length': verify_data.length
                }
            }, function (res) {
                let dataArray = [];
                let size = 0;
                res.on('data', function (data) {
                    dataArray.push(data);
                    size += data.length;
                });
                res.on('end', function () {
                    const buff = Buffer.concat(dataArray, size);
                    const result = buff.toString('utf8');
                    resolve(result);
                });
            });

            // 发送数据
            post_req.write(verify_data);
            post_req.end();
        })
    };

    const captchaResponse = await verifyCaptcha();

    console.log(JSON.parse(captchaResponse));

}

接口响应的 JSON 对象格式如下:

{
  "success": true|false,
  "challenge_ts": timestamp,  // 查询时间 (yyyy-MM-dd'T'HH:mm:ssZZ)
  "hostname": string,         // 请求 reCAPTCHA 的主机名
  "error-codes": [...]        // 错误代码
}

这样,我们就可以利用人机验证结果作响应处理。

注意,如何你的网站设置了内容安全策略,需要在 script-src 和 child-src 中放行 https://www.recaptcha.net 和 https://www.gstatic.cn。


要了解更多更新的 reCAPTCHA 介绍,请点击这里

版权声明:

本文为博主原创文章,若需转载,须注明出处,添加原文链接。

https://leeguangxing.cn/blog_post_35.html