吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3456|回复: 6
收起左侧

[其他原创] 【PHP】【recaptcha】接入谷歌recaptcha v3验证码

[复制链接]
LeoWang2021 发表于 2021-8-4 22:49
本帖最后由 LeoWang2021 于 2021-8-4 22:53 编辑

个人体验recaptcha v2也是比较烦,有时同一ip触犯到规则了,验证码会变得很烦,不是很方便。v3就解决了这个烦恼,于是我又写了一套完整的v3 demo
想看v2的可以点这里
废话不多说,上源码
index.html
[HTML] 纯文本查看 复制代码
<html>
<head>
    <title>Recaptcha隐形验证码认证</title>
    <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
    <script src="https://www.recaptcha.net/recaptcha/api.js?render=【注册的谷歌v3公钥 注意是v3!!!】"></script>
    <meta charset="UTF-8">
</head>
<body>
<h1>Recaptcha v3 隐形验证码认证</h1>
<form id="dataForm" action="confirm.php" method="post">
    <button type="submit">验证</button>
</form>
<script>
    $('#dataForm').submit(function (event) {
        event.preventDefault();
        grecaptcha.ready(function () {
            grecaptcha.execute('【同上,公钥】', {action: 'UnionLogin'}).then(function (token) {
                dataForm = $('#dataForm')
                dataForm.prepend('<input type="hidden" name="token" value="' + token + '">');
                dataForm.prepend('<input type="hidden" name="action" value="UnionLogin">');
                dataForm.unbind('submit').submit();
            });
        });
    });
</script>
</body>
</html>
confirm.php
[PHP] 纯文本查看 复制代码
<?php
define("RECAPTCHA_V3_SECRET_KEY", '【谷歌申请的网站私钥,不要泄露给别人,同样是v3】');
$token = $_POST['token'];
$action = $_POST['action'];
//echo $token;

function dfsockopen($url, $limit = 0, $post = '', $cookie = '', $bysocket = FALSE, $ip = '', $timeout = 15, $block = TRUE, $encodetype = 'URLENCODE', $allowcurl = TRUE, $position = 0, $files = array())
{
    require_once 'filesock.php';
    return _wfsockopen($url, $limit, $post, $cookie, $bysocket, $ip, $timeout, $block, $encodetype, $allowcurl, $position, $files);
}

//获取结果
$response = dfsockopen("https://www.recaptcha.net/recaptcha/api/siteverify", 0, array('secret' => RECAPTCHA_V3_SECRET_KEY, 'response' => $token));
$arrResponse = json_decode($response, true);

//验证结果
if ($arrResponse["success"] == '1' && $arrResponse["action"] == $action && $arrResponse["score"] >= 0.5) {
//    验证通过
    echo 'yes'.'<br>';
} else {
//    验证失败
    echo 'no'.'<br>';
}
//输出调试参数
echo $arrResponse["success"] . '<br>';
echo $arrResponse["action"] . '<br>';
echo $arrResponse["score"] . '<br>';

filesock.php
[PHP] 纯文本查看 复制代码
<?php

/*
 * WatermlonCloud Function
 * You can use _wfsockopen function to send POST
*/

function _isLocalip($ip)
{
    $iplong = ip2long($ip);
    return ($iplong >= 167772160 && $iplong <= 184549375) ||
        ($iplong >= 2886729728 && $iplong <= 2887778303) ||
        ($iplong >= 1681915904 && $iplong <= 1686110207) ||
        ($iplong >= 3232235520 && $iplong <= 3232301055) ||
        ($iplong >= 150994944 && $iplong <= 167772159);
}

function _parse_url($url)
{
    global $_G;
    $tmp = parse_url($url);
    if (!$tmp || empty($tmp['host'])) return false;
    if (isset($tmp['user']) || isset($tmp['pass'])) return false;
    if (strpbrk($tmp['host'], ':#?[]') !== false) return false;
    if (!in_array(strtolower($tmp['scheme']), array('http', 'https'))) {
        return false;
    }
    $config = $_G['config']['security']['fsockopensafe'];

    $ip = gethostbyname($tmp['host']);
    if ($ip == $tmp['host']) {
        return false;
    }
    if (filter_var($tmp['host'], FILTER_VALIDATE_IP) && _isLocalip($tmp['host'])) {
        return false;
    }

    if (!empty($config['port']) && isset($tmp['port'])) {
        if (isset($_SERVER['SERVER_PORT']) && !in_array($_SERVER['SERVER_PORT'], $config['port'])) {
            $config['port'][] = $_SERVER['SERVER_PORT'];
        }
        if (!in_array($tmp['port'], $config['port'])) {
            return false;
        }
    }

    if (!isset($tmp['port'])) {
        $tmp['port'] = strtolower($tmp['scheme']) == 'https' ? 443 : 80;
    }

    if ($ip) {
        if (!_isLocalip($ip)) {
            $tmp['ip'] = $ip;
            return $tmp;
        }
    } else {
        return $tmp;
    }
}

function _wfsockopen($url, $limit = 0, $post = '', $cookie = '', $bysocket = FALSE, $ip = '', $timeout = 15, $block = TRUE, $encodetype = 'URLENCODE', $allowcurl = TRUE, $position = 0, $files = array())
{
    $return = '';
    $matches = _parse_url($url);
    if (!$matches) {
        return '';
    }
    $ip = isset($matches['ip']) ? $matches['ip'] : $ip;
    $scheme = $matches['scheme'];
    $host = $matches['host'];
    if ($ip && _isLocalip($ip)) {
        return '';
    }
    $path = $matches['path'] ? $matches['path'] . ($matches['query'] ? '?' . $matches['query'] : '') : '/';
    $port = !empty($matches['port']) ? $matches['port'] : ($scheme == 'http' ? '80' : '');
    $boundary = $encodetype == 'URLENCODE' ? '' : random(40);

    if ($post) {
        if (!is_array($post)) {
            parse_str($post, $post);
        }
        _format_postkey($post, $postnew);
        $post = $postnew;
    }
    if (function_exists('curl_init') && function_exists('curl_exec') && $allowcurl) {
        $ch = curl_init();
        $httpheader = array();
        if ($ip) {
            $httpheader[] = "Host: " . $host;
        }
        $httpheader[] = "User-Agent: " . $_SERVER['HTTP_USER_AGENT'];
        if ($httpheader) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $httpheader);
        }
        curl_setopt($ch, CURLOPT_URL, $scheme . '://' . ($ip ? $ip : $host) . ($port ? ':' . $port : '') . $path);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HEADER, 1);
        if ($post) {
            curl_setopt($ch, CURLOPT_POST, 1);
            if ($encodetype == 'URLENCODE') {
                curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
            } else {
                foreach ($post as $k => $v) {
                    if (isset($files[$k])) {
                        $post[$k] = '@' . $files[$k];
                    }
                }
                foreach ($files as $k => $file) {
                    if (!isset($post[$k]) && file_exists($file)) {
                        $post[$k] = '@' . $file;
                    }
                }
                curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
            }
        }
        if ($cookie) {
            curl_setopt($ch, CURLOPT_COOKIE, $cookie);
        }
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
        curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
        $data = curl_exec($ch);
        $status = curl_getinfo($ch);
        $errno = curl_errno($ch);
        curl_close($ch);
        if ($errno || $status['http_code'] != 200) {
            return;
        } else {
            $GLOBALS['filesockheader'] = substr($data, 0, $status['header_size']);
            $data = substr($data, $status['header_size']);
            return !$limit ? $data : substr($data, 0, $limit);
        }
    }

    if ($post) {
        if ($encodetype == 'URLENCODE') {
            $data = http_build_query($post);
        } else {
            $data = '';
            foreach ($post as $k => $v) {
                $data .= "--$boundary\r\n";
                $data .= 'Content-Disposition: form-data; name="' . $k . '"' . (isset($files[$k]) ? '; filename="' . basename($files[$k]) . '"; Content-Type: application/octet-stream' : '') . "\r\n\r\n";
                $data .= $v . "\r\n";
            }
            foreach ($files as $k => $file) {
                if (!isset($post[$k]) && file_exists($file)) {
                    if ($fp = @fopen($file, 'r')) {
                        $v = fread($fp, filesize($file));
                        fclose($fp);
                        $data .= "--$boundary\r\n";
                        $data .= 'Content-Disposition: form-data; name="' . $k . '"; filename="' . basename($file) . '"; Content-Type: application/octet-stream' . "\r\n\r\n";
                        $data .= $v . "\r\n";
                    }
                }
            }
            $data .= "--$boundary\r\n";
        }
        $out = "POST $path HTTP/1.0\r\n";
        $header = "Accept: */*\r\n";
        $header .= "Accept-Language: zh-cn\r\n";
        $header .= $encodetype == 'URLENCODE' ? "Content-Type: application/x-www-form-urlencoded\r\n" : "Content-Type: multipart/form-data; boundary=$boundary\r\n";
        $header .= 'Content-Length: ' . strlen($data) . "\r\n";
        $header .= "User-Agent: $_SERVER[HTTP_USER_AGENT]\r\n";
        $header .= "Host: $host:$port\r\n";
        $header .= "Connection: Close\r\n";
        $header .= "Cache-Control: no-cache\r\n";
        $header .= "Cookie: $cookie\r\n\r\n";
        $out .= $header;
        $out .= $data;
    } else {
        $out = "GET $path HTTP/1.0\r\n";
        $header = "Accept: */*\r\n";
        $header .= "Accept-Language: zh-cn\r\n";
        $header .= "User-Agent: $_SERVER[HTTP_USER_AGENT]\r\n";
        $header .= "Host: $host:$port\r\n";
        $header .= "Connection: Close\r\n";
        $header .= "Cookie: $cookie\r\n\r\n";
        $out .= $header;
    }

    $fpflag = 0;
    if (!$fp = @fsocketopen(($scheme == 'https' ? 'ssl://' : '') . ($scheme == 'https' ? $host : ($ip ? $ip : $host)), $port, $errno, $errstr, $timeout)) {
        $context = array(
            'http' => array(
                'method' => $post ? 'POST' : 'GET',
                'header' => $header,
                'content' => $post,
                'timeout' => $timeout,
            ),
        );
        $context = stream_context_create($context);
        $fp = @fopen($scheme . '://' . ($scheme == 'https' ? $host : ($ip ? $ip : $host)) . ':' . $port . $path, 'b', false, $context);
        $fpflag = 1;
    }

    if (!$fp) {
        return '';
    } else {
        stream_set_blocking($fp, $block);
        stream_set_timeout($fp, $timeout);
        @fwrite($fp, $out);
        $status = stream_get_meta_data($fp);
        if (!$status['timed_out']) {
            while (!feof($fp) && !$fpflag) {
                $header = @fgets($fp);
                $headers .= $header;
                if ($header && ($header == "\r\n" || $header == "\n")) {
                    break;
                }
            }
            $GLOBALS['filesockheader'] = $headers;

            if ($position) {
                for ($i = 0; $i < $position; $i++) {
                    $char = fgetc($fp);
                    if ($char == "\n" && $oldchar != "\r") {
                        $i++;
                    }
                    $oldchar = $char;
                }
            }

            if ($limit) {
                $return = stream_get_contents($fp, $limit);
            } else {
                $return = stream_get_contents($fp);
            }
        }
        @fclose($fp);
        return $return;
    }
}

function _format_postkey($post, &$result, $key = '')
{
    foreach ($post as $k => $v) {
        $_k = $key ? $key . '[' . $k . ']' : $k;
        if (is_array($v)) {
            _format_postkey($v, $result, $_k);
        } else {
            $result[$_k] = $v;
        }
    }
}

?>

免费评分

参与人数 5吾爱币 +10 热心值 +5 收起 理由
youliang + 1 用心讨论,共获提升!
ytw6176 + 2 + 1 谢谢@Thanks!
Pandaemm + 1 + 1 用心讨论,共获提升!
sdaza + 1 热心回复!
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| LeoWang2021 发表于 2021-8-5 15:04
ytw6176 发表于 2021-8-5 11:40
请教一下,配置好以后,点击验证,跳转confirm显示这些信息是不是表示验证通过?

我没有写中文结果,下面是数值解释
第一行 结果 yes 通过|no 不通过,只有后三项全部达标才能通过
第二行请求结果是否请求成功
第三行 action 我定的是UnionLogin,因为我是打算做账号统一登录页面,听说是用于统计 但本人也没有搞清楚,希望知道的可以解答一下
第四行评估分数也就是决定是否通过的得分,越高越好,由谷歌人工智能判定,可以自己看代码修改阈值,我定的是0.5

还是建议自己看代码,这个是demo,主要是我做出来让给大家来看调用方法的,还是需要自己修改变成产品,还是要把每一句代码搞懂
zxs4487025 发表于 2021-8-4 23:21
ytw6176 发表于 2021-8-5 11:40

QQ截图20210805113743.png

请教一下,配置好以后,点击验证,跳转confirm显示这些信息是不是表示验证通过?
QQ截图20210805113807.png
ytw6176 发表于 2021-8-5 15:12
LeoWang2021 发表于 2021-8-5 15:04
我没有写中文结果,下面是数值解释

还是建议自己看代码,这个是demo,主要是我做出来让给大家来看调用 ...

好的。。 我没看代码文档。。 直接调用,前台点击按钮,我以为会有个滑动验证码,结果啥都没有直接跳结果了。。
 楼主| LeoWang2021 发表于 2021-8-5 15:27
本帖最后由 LeoWang2021 于 2021-8-5 15:29 编辑
ytw6176 发表于 2021-8-5 15:12
好的。。 我没看代码文档。。 直接调用,前台点击按钮,我以为会有个滑动验证码,结果啥都没有直接跳结果 ...

要弹出验证码的话,看v2,我之前也发过https://www.52pojie.cn/thread-1487657-1-1.html
要滑动或者拼图的话,可以看一下极验或者腾讯防水墙,这个主要是免费
ytw6176 发表于 2021-8-5 15:48
LeoWang2021 发表于 2021-8-5 15:27
要弹出验证码的话,看v2,我之前也发过https://www.52pojie.cn/thread-1487657-1-1.html
要滑动或者拼图 ...

好的,感谢
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 07:22

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表