文章目录
  1. 1. Defined
  2. 2. import
  3. 3. Main()
    1. 3.1. demo目录结构
    2. 3.2. 前端页面
    3. 3.3. 集成类库
    4. 3.4. 控制器集成
    5. 3.5. 前端Ajax, 逻辑处理
  4. 4. 最后吐槽一下
  5. 5. 2017/10/21 update
  6. 6. Reference

Defined

怕存在不正当请求导致的服务器ddos, 采用极验验证进行部分阻挡~
参考了底下的thinkphp教程

import

Demo项目

git clone https://github.com/GeeTeam/gt-php-sdk.git

Main()

demo目录结构

1
2
3
4
5
6
7
8
9
10
11
12
gt-php-sdk/
├── composer.json #标志/可删
├── config
│   └── config.php #内建环境变量
├── lib
│   └── class.geetestlib.php #封装类库
├── README.rst
├── static
│   └── login.html #前端页面
└── web
├── StartCaptchaServlet.php #遮罩controllers
└── VerifyLoginServlet.php #验证controllers

前端页面

用的bootstrap框架

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<div class="row" id="login-div">
<div class="col-xs-10 col-xs-offset-1 col-md-4 col-md-offset-4">
<form id="form-login" action="login" method="post" role="form">
<div class="form-group">
<input type="text" class="form-control" name="username" id="user-login" placeholder="Username" tabindex="1">
</div>
<div class="form-group">
<input type="password" class="form-control" name="password" id="pass-login" placeholder="Password" tabindex="2">
</div>
<div class="form-group">
<div class="row">
<div class="col-xs-8 col-xs-offset-2 col-lg-10 col-lg-offset-1">
<input type="button" value="Login In" id="cover-submit-login" class="btn btn-success form-control">
</div>
</div>
</div>
</form>
</div>
</div>
<div id="mask"></div>
<div id="popup-captcha"></div>

集成类库

CI在application目录下有个library目录, 在里面创建一个名为Geetestlib的php文件.
内容和class一样, 通过class封装.

1
2
3
class Geetestlib {
# class.geetestlib.php's codes
}

控制器集成

改名为Geetest.php
这边的话尝试过利用$this->load->library(), 用着用着不知道怎么玩了..所以最后采取的原生require

require_once dirname(dirname(FILE)).’/libraries/Geetestlib.php’;

  1. 定义私有变量, 并设置默认构造函数
1
2
3
4
5
6
7
8
9
10
private $captcha_id;
private $private_key;
private $GtSdk;

public function __construct () {
parent::__construct();
$this->captcha_id = "xxx";
$this->private_key = "xxx";
$this->GtSdk = new GeetestLib($this->captcha_id, $this->private_key);
}
  1. 静态数据加载controller

    1
    2
    3
    4
    5
    6
    7
    8
    public function startCaptcha () {
    session_start();
    $user_id = "test";
    $status = $this->GtSdk->pre_process($user_id);
    $_SESSION['gtserver'] = $status;
    $_SESSION['user_id'] = $user_id;
    echo $this->GtSdk->get_response_str();
    }
  2. 后端验证controller

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    public function verifyLogin () {
    session_start();
    $user_id = $_SESSION['user_id'];
    if ($_SESSION['gtserver'] == 1) { //服务器正常
    $result = $this->GtSdk->success_validate($_POST['geetest_challenge'], $_POST['geetest_validate'], $_POST['geetest_seccode'], $user_id);
    if ($result) {
    echo '{"status":"success"}';
    } else{
    echo '{"status":"fail"}';
    }
    }else { //服务器宕机,走failback模式
    if ($this->GtSdk->fail_validate($_POST['geetest_challenge'], $_POST['geetest_validate'], $_POST['geetest_seccode'])) {
    echo '{"status":"success"}';
    } else {
    echo '{"status":"fail"}';
    }
    }
    }

前端Ajax, 逻辑处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
$("#mask").click(function () {
$("#mask, #popup-captcha").hide();
$('#cover-submit-login, #cover-submit-register').show();
});

$("#cover-submit-login").click(function () {
$("#mask, #popup-captcha").show();
});

/* -- login -- */
var handlerPopupLogin = function (captchaObj) {
// 将验证码加到id为captcha的元素里
captchaObj.appendTo("#popup-captcha");
//拖动验证成功后两秒(可自行设置时间)自动发生跳转等行为
captchaObj.onSuccess(function () {
var validate = captchaObj.getValidate();
$.ajax({
url: "Geetest/verifyLogin", // 进行二次验证
type: "post",
dataType: "json",
data: {
// 二次验证
username: $('#user-login').val(),
password: $('#pass-login').val(),
geetest_challenge: validate.geetest_challenge,
geetest_validate: validate.geetest_validate,
geetest_seccode: validate.geetest_seccode
},
success: function (data) {
if (data && (data.status === "success")) {
$('#form-login').submit();
// 进行form表单提交
} else {
// error operation
}
}
});
});
};
// 默认ajax状态
$.ajax({
// 获取id,challenge,success(是否启用failback)
url: "Geetest/startCaptcha/t/" + (new Date()).getTime(), // 加随机数防止缓存
type: "get",
dataType: "json",
success: function (data) {
// 使用initGeetest接口
// 参数1:配置参数
// 参数2:回调,回调的第一个参数验证码对象,之后可以使用它做appendTo之类的事件
initGeetest({
gt: data.gt,
challenge: data.challenge,
offline: !data.success // 表示用户后台检测极验服务器是否宕机,一般不需要关注
// 更多配置参数请参见:http://www.geetest.com/install/sections/idx-client-sdk.html#config
}, handlerPopupLogin);
}
});

最后吐槽一下

极验官方下载的前端demo和官网的前端两个样, 最后参照了一下官网…

自己用的其实是mobile端的验证, 由于前端的input一开始写的type="submit", 所以导致每次点击都无法加载完现验证页面.
最后采用了button类型, 成功进行form表单提交解决.

给个geetest官网的解决方案(自己实现过, 但是不适用):
创建两个一模一样的input, 一个类型为button, 另一个为submit, button默认display=block
input点击之后出现验证页面, 更改show和hide状态, submit的input上线~, 验证页面在ajax成功后xxms后关闭.
重新进行点击, 完成表单提交. (感觉自己这个实现有点傻, 不过就是这样的..)

2017/10/21 update

  1. 关于CI的封装library配置, 默认GtSdk类的constructor继承需要两个参数, 然而需要两个, 所以在class文件单独配置, 改为$arr, 里面单独赋值即可.
  2. 极验3.0了, 官方的demo依旧感人, 最好的demo是他在线的网页demo.离线demo建议只看后端部分

Reference

实例thinkphp如何使用极验验证码 让验证有趣起来-高蒙
极验前端

文章目录
  1. 1. Defined
  2. 2. import
  3. 3. Main()
    1. 3.1. demo目录结构
    2. 3.2. 前端页面
    3. 3.3. 集成类库
    4. 3.4. 控制器集成
    5. 3.5. 前端Ajax, 逻辑处理
  4. 4. 最后吐槽一下
  5. 5. 2017/10/21 update
  6. 6. Reference