致敬学习的自己,非计算机专业的程序员就只会写功能,不会讲原理、不会讲算法、就是会被歧视吗,管他大爷的,今天做一个拖动的验证码功能,
极验官网:https://www.geetest.com/
- 后台接口有两个,一个初始化,一个二次验证
- 获取到php-SDK后 在lib文件夹有一个class.geetestlib.php的文件,后台我们只需要这个文件就可以了
- 至于config里面的常量"CAPTCHA_ID" "PRIVATE_KEY",配置到框架中去
整个流程
进入页面请求api1->取得参数初始化initGeetest方法渲染到id=captcha的div内->点击验证->执行captchaObj.onSuccess 在里面进行第二次验证 api2->成功后返回到页面把提交按钮的disabled打开,允许登录
1、laravel引入极验第三方类
- 把Lib文件夹复制到laravel项目的app目录下,修改class.geetestlib.php为GeetestLib.php
- 接着找到根目录下的composer.json文件
"autoload": {
"classmap": [
"database/seeds",
"database/factories",
"app/Lib/GeetestLib.php" // 加入配置
],
"psr-4": {
"App\\": "app/"
}
}
- 在项目的根目录执行命令
composer dumpautoload
- 然后就能在项目中愉快的使用了,简单的用法如下:
use GeetestLib; // 极验类库
2、获取验证条样式(前台),初始化接口 API1(后台)
#前台部分
<div class="login">
<div class="message">管理登录</div>
<div id="darkbannerwrap"></div>
<form method="post" class="layui-form" >
<input name="phone" placeholder="电话号码" type="text" lay-verify="required" class="layui-input" >
<hr class="hr15">
<input name="password" lay-verify="required" placeholder="密码" type="password" class="layui-input">
<hr class="hr15">
<div id="captcha">
<div id="loading-tip">加载中,请稍后...</div>
</div>
<hr class="hr15" >
<input value="登录" lay-submit lay-filter="login" id="submit-tip" style="width:100%;" type="submit">
<hr class="hr20" >
</form>
</div>
// 渲染 验证条
var handler = function (captchaObj) {
// DOM 准备好后,隐藏 #loading-tip 元素
// 仅作示例用,用您适合的方式隐藏即可
captchaObj.onReady(function () {
document.getElementById('loading-tip').style.display = 'none';
$("#submit-tip").attr("disabled",true); //
});
// 出错啦,可以提醒用户稍后进行重试
captchaObj.onError(function () {
layer.msg('页面出错,请刷新页面。。。', {icon: 5});
});
// 将验证码加到id为captcha的元素里
// 渲染验证条
captchaObj.appendTo("#captcha");
};
// api1 获取流水标识并设置状态码
$.ajax({
url: loginurl+"Rbac/apiVerif1", // 验证码的第一次验证 接口
type: "get",
dataType: "json",
success: function (data) {
//请检测data的数据结构, 保证data.gt, data.challenge, data.success有值
initGeetest({
gt: data.gt,
challenge: data.challenge,
product: "float", // 产品形式
offline: !data.success
}, handler); // 参数配置完以后执行上面的handler方法 渲染验证条
}
})
#后台部分
// 验证码的第一次验证
public function apiVerif1(Request $request){
// 极验类的库,传入CAPTCHA_ID 和 PRIVATE_KEY
// 在极验后台有,写到配置文件中去
$GtSdk = new \GeetestLib(config('constants.CAPTCHA_ID'), config('constants.PRIVATE_KEY'));
$data = array(
"user_id" => uniqid(), # 网站用户id
"client_type" => "web", #web:电脑上的浏览器;h5:手机上的浏览器,包括移动应用内完全内置的web_view;native:通过原生SDK植入APP应用的方式
"ip_address" => $request->getClientIp(), # 请在此处传输用户请求验证时所携带的IP
);
$status = $GtSdk->pre_process($data, 1); // 获取服务器的状态
session(['gtserver' => $status]);// 状态存入session中
session(['user_id' => $data['user_id']]);// 用户id存入session中
echo $GtSdk->get_response_str(); // 传到前台 供initGeetest使用 data.gt, data.challenge, data.success
}
上面执行完后在id=captcha会出现 验证条
image.png
3、点击验证条(前台),后台二次验证 API2(后台)
-
点击验证条后会出现
image.png -
验证完成后会出现
image.png
在代码中执行了什么操作呢?
- 完成后会执行 handler 方法中的onSuccess, 在这个方法内进行第二次验证
- 在页面上会出现三个input 它们name分别为 geetest_challenge, geetest_validate,geetest_validate
captchaObj.onSuccess(function () {
})
// 验证码成功以后会执行的方法,但不代表验证成功
captchaObj.onSuccess(function () {
var result = captchaObj.getValidate();
// api2 查询验证是否成功
$.ajax({
url: loginurl+"Rbac/apiVerif2", // 二次验证的接口地址
type: "post",
data: {
geetest_challenge: result.geetest_challenge,
geetest_validate: result.geetest_validate,
geetest_seccode: result.geetest_seccode,
// 其他服务端需要的数据,比如登录时的用户名和密码
},
dataType: "json",
success: function (data) {
if( data.code === 0 ){
$("#submit-tip").attr("disabled",false);
}else{
layer.msg('验证失败', {icon: 5});
captchaObj.reset(); // 调用该接口进行重置
}
}
})
})
# 后台代码
// 验证码的第二次验证
public function apiVerif2(Request $request){
$info = $request->all();
// 判断服务器是否正常
$gtserver = session()->pull('gtserver');
// 用户的id 一个随机数
$user_id = session()->pull('user_id');
$GtSdk = new \GeetestLib(config('constants.CAPTCHA_ID'), config('constants.PRIVATE_KEY'));
$data = array(
"user_id" => $user_id, # 网站用户id
"client_type" => "web", #web:电脑上的浏览器;h5:手机上的浏览器,包括移动应用内完全内置的web_view;native:通过原生SDK植入APP应用的方式
"ip_address" => $request->getClientIp(), # 请在此处传输用户请求验证时所携带的IP
);
if ( $gtserver == 1) { // 服务器正常
$result = $GtSdk->success_validate($info['geetest_challenge'], $info['geetest_validate'], $info['geetest_seccode'], $data);
if ($result) {
Base::successReturn('验证成功', 0, "success"); // echo '{"status":"success"}';
}
Base::errorReturn('验证失败', 300);
} else { // 服务器宕机,走failback模式
if ($GtSdk->fail_validate($info['geetest_challenge'],$info['geetest_validate'],$info['geetest_seccode'])) {
Base::successReturn('验证成功', 0, "success");
}
Base::errorReturn('验证失败', 300);
}
}
网友评论