【thinkphp】极验3.0的配置方法

ThinkPHP\Library\Vendor\Geetest\Geetestlib.php

<?php

/**
 * 极验行为式验证安全平台,php 网站主后台包含的库文件
 *
 * @author Tanxu
 */
class GeetestLib {
    const GT_SDK_VERSION = 'php_3.0.0';
    public static $connectTimeout = 1;
    public static $socketTimeout  = 1;

    private $response;

    public function __construct($captcha_id, $private_key) {
        $this->captcha_id  = $captcha_id;
        $this->private_key = $private_key;
    }

    /**
     * 判断极验服务器是否down机
     *
     * @param array $data
     * @return int
     */
    public function pre_process($param, $new_captcha=1) {
        $data = array('gt'=>$this->captcha_id,
                     'new_captcha'=>$new_captcha
                );
        $data = array_merge($data,$param);
        $query = http_build_query($data);
        $url = "http://api.geetest.com/register.php?" . $query;
        $challenge = $this->send_request($url);
        if (strlen($challenge) != 32) {
            $this->failback_process();
            return 0;
        }
        $this->success_process($challenge);
        return 1;
    }

    /**
     * @param $challenge
     */
    private function success_process($challenge) {
        $challenge      = md5($challenge . $this->private_key);
        $result         = array(
            'success'   => 1,
            'gt'        => $this->captcha_id,
            'challenge' => $challenge,
            'new_captcha'=>1
        );
        $this->response = $result;
    }

    /**
     *
     */
    private function failback_process() {
        $rnd1           = md5(rand(0, 100));
        $rnd2           = md5(rand(0, 100));
        $challenge      = $rnd1 . substr($rnd2, 0, 2);
        $result         = array(
            'success'   => 0,
            'gt'        => $this->captcha_id,
            'challenge' => $challenge,
            'new_captcha'=>1
        );
        $this->response = $result;
    }

    /**
     * @return mixed
     */
    public function get_response_str() {
        return json_encode($this->response);
    }

    /**
     * 返回数组方便扩展
     *
     * @return mixed
     */
    public function get_response() {
        return $this->response;
    }

    /**
     * 正常模式获取验证结果
     *
     * @param string $challenge
     * @param string $validate
     * @param string $seccode
     * @param array $param
     * @return int
     */
    public function success_validate($challenge, $validate, $seccode,$param, $json_format=1) {
        if (!$this->check_validate($challenge, $validate)) {
            return 0;
        }
        $query = array(
            "seccode" => $seccode,
            "timestamp"=>time(),
            "challenge"=>$challenge,
            "captchaid"=>$this->captcha_id,
            "json_format"=>$json_format,
            "sdk"     => self::GT_SDK_VERSION
        );
        $query = array_merge($query,$param);
        $url          = "http://api.geetest.com/validate.php";
        $codevalidate = $this->post_request($url, $query);
        $obj = json_decode($codevalidate,true);
        if ($obj === false){
            return 0;
        }
        if ($obj['seccode'] == md5($seccode)) {
            return 1;
        } else {
            return 0;
        }
    }

    /**
     * 宕机模式获取验证结果
     *
     * @param $challenge
     * @param $validate
     * @param $seccode
     * @return int
     */
    public function fail_validate($challenge, $validate, $seccode) {
        if(md5($challenge) == $validate){
            return 1;
        }else{
            return 0;
        }
    }

    /**
     * @param $challenge
     * @param $validate
     * @return bool
     */
    private function check_validate($challenge, $validate) {
        if (strlen($validate) != 32) {
            return false;
        }
        if (md5($this->private_key . 'geetest' . $challenge) != $validate) {
            return false;
        }

        return true;
    }

    /**
     * GET 请求
     *
     * @param $url
     * @return mixed|string
     */
    private function send_request($url) {

        if (function_exists('curl_exec')) {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, self::$connectTimeout);
            curl_setopt($ch, CURLOPT_TIMEOUT, self::$socketTimeout);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            $curl_errno = curl_errno($ch);
            $data = curl_exec($ch);
            curl_close($ch);
            if ($curl_errno >0) {
                return 0;
            }else{
                return $data;
            }
        } else {
            $opts    = array(
                'http' => array(
                    'method'  => "GET",
                    'timeout' => self::$connectTimeout + self::$socketTimeout,
                )
            );
            $context = stream_context_create($opts);
            $data    = @file_get_contents($url, false, $context);
            if($data){ 
                return $data;
            }else{ 
                return 0;
            } 
        }
    }

    /**
     *
     * @param       $url
     * @param array $postdata
     * @return mixed|string
     */
    private function post_request($url, $postdata = '') {
        if (!$postdata) {
            return false;
        }

        $data = http_build_query($postdata);
        if (function_exists('curl_exec')) {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, self::$connectTimeout);
            curl_setopt($ch, CURLOPT_TIMEOUT, self::$socketTimeout);

            //不可能执行到的代码
            if (!$postdata) {
                curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
            } else {
                curl_setopt($ch, CURLOPT_POST, 1);
                curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
            }
            $data = curl_exec($ch);

            if (curl_errno($ch)) {
                $err = sprintf("curl[%s] error[%s]", $url, curl_errno($ch) . ':' . curl_error($ch));
                $this->triggerError($err);
            }

            curl_close($ch);
        } else {
            if ($postdata) {
                $opts    = array(
                    'http' => array(
                        'method'  => 'POST',
                        'header'  => "Content-type: application/x-www-form-urlencoded\r\n" . "Content-Length: " . strlen($data) . "\r\n",
                        'content' => $data,
                        'timeout' => self::$connectTimeout + self::$socketTimeout
                    )
                );
                $context = stream_context_create($opts);
                $data    = file_get_contents($url, false, $context);
            }
        }

        return $data;
    }


    
    /**
     * @param $err
     */
    private function triggerError($err) {
        trigger_error($err);
    }
}

App\Home\Common\function.php

function VerifyLoginServlet($geetest_challenge,$geetest_validate,$geetest_seccode){
    vendor("Geetest.Geetestlib");
    $GtSdk=new \GeetestLib(C('CAPTCHA_ID'), C('PRIVATE_KEY'));
    $data = array(
        "user_id" => session_id(), # 网站用户id
        "client_type" => "web", #web:电脑上的浏览器;h5:手机上的浏览器,包括移动应用内完全内置的web_view;native:通过原生SDK植入APP应用的方式
        "ip_address" => get_client_ip() # 请在此处传输用户请求验证时所携带的IP
    );
    if (session('gtserver')==1){//服务器正常
        $result = $GtSdk->success_validate($geetest_challenge,$geetest_validate,$geetest_seccode, $data);
        if ($result) {
            return true;
        } else{
            return false;
        }     
    }else {//服务器宕机,走failback模式
        $result = $GtSdk->success_validate($geetest_challenge,$geetest_validate,$geetest_seccode, $data);
        if ($result) {
            return true;
        } else{
            return false;
        }        
    }   
}

在页面引入<script src="__PUBLIC__/Home/js/gt.js"></script>

     var handlerEmbed = function (captchaObj) {
	        captchaObj.appendTo("#captcha-box");     	
			$('#submitbtn').click(function(e) {
	            var validate = captchaObj.getValidate();
	            if (!validate) {
	                layer.msg("请先完成验证",{icon: 5});
	                return false;
	            }						
				$("form").ajaxSubmit({
					type: 'post',
					url: "{:U('Home/login/loginCheck')}",
					success: function(data) {
						if(data==true){
						layer.alert("登录成功",{ icon: 4, time: 1000 });
						window.location.href='{:U('Home/Member/index')}';									
						}else{
							layer.alert(data,{ icon: 5, time: 1000 });
							captchaObj.reset();
						}						
					},
				});
				return false; 
			})     	
     	
    };   
    $.ajax({
        url: "{:U('Login/StartCaptchaServlet')}?t=" + (new Date()).getTime(), // 加随机数防止缓存
        type: "get",
        dataType: "json",
        success: function (data) {
            initGeetest({
                gt: data.gt,
                challenge: data.challenge,
                new_captcha: data.new_captcha,
                product: "embed", // 产品形式,包括:float,embed,popup。注意只对PC版验证码有效
                offline: !data.success, // 表示用户后台检测极验服务器是否宕机,一般不需要关注
                width: '100%'
                // 更多配置参数请参见:http://www.geetest.com/install/sections/idx-client-sdk.html#config
            }, handlerEmbed);
        }
    });

App\Home\Controller\LoginController.class.php

    /*
     * 极验验证码
     * 2017年9月15日 14:02:23
     */
    public function StartCaptchaServlet(){
        vendor("Geetest.Geetestlib");
        $GtSdk=new \GeetestLib(C('CAPTCHA_ID'), C('PRIVATE_KEY'));
        $data = array(
            "user_id" => session_id(), # 网站用户id
            "client_type" => "web", #web:电脑上的浏览器;h5:手机上的浏览器,包括移动应用内完全内置的web_view;native:通过原生SDK植入APP应用的方式
            "ip_address" => get_client_ip() # 请在此处传输用户请求验证时所携带的IP
        );    
        $status = $GtSdk->pre_process($data, 1);
        session('gtserver',$status);
        session('user_id',$data['user_id']);
        echo $GtSdk->get_response_str();
        exit();
    }

App\Common\Conf\config.php

<?php
return array(
	//'配置项'=>'配置值'
    //极验配置
    'CAPTCHA_ID' =>'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
    'PRIVATE_KEY' =>'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
);
<!--给合适的地方加上验证码容器-->
<div id="captcha-box"></div>

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏云计算教程系列

为你的网站加一道防线,腾讯云服务器安装配置SimpleSAMLphp指南

SimpleSAMPLphp是一个开源的PHP身份验证应用程序,它作为服务提供者(SP)以及身份提供者(IdP)来为 SAML 2.0提供支持。

3034
来自专栏信安之路

审计SEMCMSv2.7之捡来的两个洞加漏洞复现

在 SEMCMS php v2.7 审计之前,我会去看看要审计的CMS官网是否存在手册说明什么的,然后去会各个漏洞公布平台找找它以前的老漏洞,复现下是否修复及修...

1160
来自专栏雪胖纸的玩蛇日常

django 通过ajax完成邮箱用户注册、激活账号

4707
来自专栏linux系统运维

Nginx安装, 默认虚拟主机,Nginx用户认证,Nginx域名重定向

39811
来自专栏Ken的杂谈

Nginx配置SSL证书将网站从HTTP升级到HTTPS

HTTPS全称是:超文本安全传输协议,可以简单理解为使用SSL加密传输的HTTP协议,HTTP的默认端口是80,HTTPS的默认端口是443。SSL是为网络通信...

6514
来自专栏运维小白

12.6 Nginx安装

Nginx安装目录概要 cd /usr/local/src wget http://nginx.org/download/nginx-1.12.1.tar.gz...

3467
来自专栏龙首琴剑庐

Tomcat6/7应用服务器-禁用RC4等弱密码套件

最近更新了新版浏览器的同学是不是偶尔会遇到SSL加密协议不灵,访问不了的情况? 最典型的例子是使用FF39+访问某些网站时报错:Error code: ssl...

4335
来自专栏Laoqi's Linux运维专列

LNMP搭建多个虚拟主机(wordpress+discuz+dedecms)

4496
来自专栏张戈的专栏

Linux系统编译安装Redis以及主从复制配置小记

Redis 的安装配置很简单,而且很早之前就装过 Redis,可这几天再次安装时居然又遗忘了一些细节,看来好记性不如烂笔头,还是在博客记录一下比较好,至少不用总...

2853
来自专栏緣來來來

申请Let's Encrypt通配符证书

Let's Encrypt支持通配符证书了,也就是说你只需要为你的网站申请*.example.com这样一个证书,所有的子域名都可以支持,下面介绍下申请方法:

5662

扫码关注云+社区

领取腾讯云代金券