分享经验 版主:论坛审计组
滑块验证码的插件实现方法(开源免费)
类型:迅睿CMS 更新时间:2024-07-18 15:15:17 上传文件

滑块验证码的插件实现方法

本文使用的是第三方验证服务 -极验验证码4.0

如使用上有问题可联系我-将持续免费开源更新

--下载页可以隐藏当前下载地址(支持上传文件和输入文件地址)

去官网申请账号,本插件基于免费版开发,https://console.geetest.com/sensbot/management

滑块验证码教程

创建业务模块

滑块验证码教程

新增业务场景

滑块验证码教程

获取到id和key

滑块验证码教程

3、添加极验id和key 

滑块验证码教程
滑块验证码教程

功能配置

https://www.xunruicms.com/book/17/83.html

回帖
  • 又菜又爱玩
    #1楼    又菜又爱玩
    2024-07-18 14:17:09
    Firefox 128.0 0

    2024/07/18 更新 下载页适配

    所有代码下载链接回复后自取:

    https://file.xunruicms.com/gwbbs/ueditor/file/202407/17212831392a194d.zip

    使用方式:

    根目录解压缩

  • 又菜又爱玩
    #2楼    又菜又爱玩
    2024-07-18 15:10:50
    Firefox 128.0 0
    主要逻辑文件在dayrui\App\Geetest\Controllers\api.php中举例 下载页验证实现逻辑:
     public function down()
        {
            error_reporting(0);
    
            // 点击下载验证后 会通过get方式获取到前端极验的别名
             $cname = $_GET['cname'];
             //这里做一个判断别名空值
             if(!$cname){
                \Phpcmf\Service::C()->_json(0, dr_lang('获取极验别名为空,请检查'));
            }
            //通过别名获取极验后台录入的id以及key
            $captcha_id = dr_geetest($cname, 2);
            $captcha_key = dr_geetest($cname, 3);
    
            // 定义极验备用服务器地址
            $api_servers = [
                "http://gcaptcha4.geetest.com",
                "http://gcaptcha4.geevisit.com",
                "http://gcaptcha4.gsensebot.com"
                
            ];
    
            // 获取用户验证后前端传过来的验证流水号参数“这边是极验回传的参数”
            $lot_number = $_GET['lot_number'];
            $captcha_output = $_GET['captcha_output'];
            $pass_token = $_GET['pass_token'];
            $gen_time = $_GET['gen_time'];
    
            // 3. 生成签名
            $sign_token = hash_hmac('sha256', $lot_number, $captcha_key);
    
            // 4. 上传校验参数到极验二次验证接口,校验用户验证状态
            $result = $this->validateCaptcha($api_servers, $captcha_id, $lot_number, $captcha_output, $pass_token, $gen_time, $sign_token);
    
            // 5. 根据极验返回的用户验证状态,进行自定义业务逻辑(这里只写了验证通过,不通过则给提示)
            $status = $result['result']; 
            $reason = $result['reason']; 
            
            //二次验证通过
            if ($status == 'success') {
              
                //通过get方式获取前端下载页地址
                $currentUrl = \Phpcmf\Service::L('input')->get('currentUrl');
                //通过PHP 内置的 parse_url 函数,获取?号之后的代码 “s=api&c=file&m=down&id=fec5ebe1ba6e6d5863ad6aa569cd9078”
                $queryString = parse_url($currentUrl, PHP_URL_QUERY);
                //arse_str函数,是把后面的地址,解析成一个数组 “s=api  c=file...”
                parse_str($queryString, $params);
                //把“id=fec5ebe1ba6e6d5863ad6aa569cd9078”赋值给id,下面是官方的一个读取附件的代码
                $id = $params['id'];
                //判断 $id 是否是数字
                if (is_numeric($id)) {
                //纯数字就是你跳转过来的内容页的id
                    $rt = [
                        'id' => $id,
                        'name' => dr_safe_replace(\Phpcmf\Service::L('input')->get('name')),
                    ];
                } 
                //判断是否32位的字符串 “id=fec5ebe1ba6e6d5863ad6aa569cd9078”
                elseif (strlen((string)$id) == 32) {
                //是的话就找缓存文件(上传文件都是有一个缓存文件存储)
                    $rt = \Phpcmf\Service::L('cache')->get_auth_data('down-file-'.$id);
                    if (!$rt) {
                        $this->_msg(0, dr_lang('此附件下载链接已经失效'));
                    }
                } 
                //如果都不是,直接返回id
                else {
                    $rt = [
                        'id' => dr_safe_replace(urldecode($id)),
                        'name' => dr_safe_replace(\Phpcmf\Service::L('input')->get('name')),
                    ];
                }
                
                
                //然后通过把上面获取到的id赋值
                $id = trim($rt['id']);
                //通过上传文件缓存获取对应的url下载链接
                $data = \Phpcmf\Service::L('cache')->get_file('attach-info-'. $id, 'attach');
                判断是否有文件缓存文件
                if($data){
                //有的话返回出缓存文件内的url地址
                    $url = $data['url']; 
                 }else{
                 //如果没有的话直接返回id(这个位置是根据官方附件获取逻辑写的,没有获取缓存文件的地址,代表可能是你手动输入的地址,而这里的id会直接获取到文件下载地址)
                     $url = $rt['id']; 
                 }
                 // 获取验证成功后的 URL 返回后前端使用ajax获取下载地址
                echo sprintf('{"status":"%s","url":"%s"}', $status, $url);
               
            } else {
                // 在验证失败时执行的代码,只返回状态码
                echo sprintf('{"status":"%s","reason":"%s"}', $status, $reason);
            }
            
               
        }
  • 又菜又爱玩
    #3楼    又菜又爱玩
    2024-07-18 15:15:17
    Firefox 128.0 0
    其他自己开发业务,只需要自己中间验证成功后写api,前端回传即可
    public function test()
        {
            error_reporting(0);
    
            // 点击下载验证后 会通过get方式获取到前端极验的别名
             $cname = $_GET['cname'];
             //这里做一个判断别名空值
             if(!$cname){
                \Phpcmf\Service::C()->_json(0, dr_lang('获取极验别名为空,请检查'));
            }
            //通过别名获取极验后台录入的id以及key
            $captcha_id = dr_geetest($cname, 2);
            $captcha_key = dr_geetest($cname, 3);
    
            // 定义极验备用服务器地址
            $api_servers = [
                "http://gcaptcha4.geetest.com",
                "http://gcaptcha4.geevisit.com",
                "http://gcaptcha4.gsensebot.com"
                
            ];
    
            // 获取用户验证后前端传过来的验证流水号参数“这边是极验回传的参数”
            $lot_number = $_GET['lot_number'];
            $captcha_output = $_GET['captcha_output'];
            $pass_token = $_GET['pass_token'];
            $gen_time = $_GET['gen_time'];
    
            // 3. 生成签名
            $sign_token = hash_hmac('sha256', $lot_number, $captcha_key);
    
            // 4. 上传校验参数到极验二次验证接口,校验用户验证状态
            $result = $this->validateCaptcha($api_servers, $captcha_id, $lot_number, $captcha_output, $pass_token, $gen_time, $sign_token);
    
            // 5. 根据极验返回的用户验证状态,进行自定义业务逻辑(这里只写了验证通过,不通过则给提示)
            $status = $result['result']; 
            $reason = $result['reason']; 
            
            //二次验证通过
            if ($status == 'success') {
              
               //自己的业务代码
            
            } else {
                // 在验证失败时执行的代码,只返回状态码
                echo sprintf('{"status":"%s","reason":"%s"}', $status, $reason);
            }
            
               
        }