geetest

简述

在网站开发中使用频率最高的工具之一便是验证码,验证码在此也是多种多样,不过简单的图片验证码已经可以被机器识别,极验验证码提供了一个安全可靠的滑动验证码体系,让网站开发更加安全。

安装

下载SDK

使用命令从Github导入完整项目

1
git clone https://github.com/GeeTeam/gt3-dotnet-sdk.git

手动下载压缩包文件

Github: gt3-python-sdk下载.zip文件

引入SDK

使用VS打开项目中SDK的.sln文件即可引入SDK。

在您的项目中使用以下代码即可导入SDK

1
using GeetestSDK;

配置密钥,修改请求参数

配置密钥

极验管理后台获取您的公钥(id)和私钥(key), 并在代码中配置。配置文件路径如下:

1
/demo/GeetestConfig.cs

修改请求参数(可选)

名称 说明
user_id 用户标识,若担心用户信息风险,可作预处理(如哈希处理)再提供
client_type 客户端类型,web(pc浏览器),h5(手机浏览器,包括webview),native(原生app),unknown(未知)
ip_address 客户端请求您服务器的ip地址,unknow表示未知

接口示例

初始化(API1),获取流水标识并设置状态码)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
namespace demo
{
public partial class GetCaptcha : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Response.ContentType = "application/json";
Response.Write(getCaptcha());
Response.End();
}
private String getCaptcha()
{
GeetestLib geetest = new GeetestLib(GeetestConfig.publicKey, GeetestConfig.privateKey);
String userID = "test";
Byte gtServerStatus = geetest.preProcess(userID,"web","127.0.0.1");
Session[GeetestLib.gtServerStatusSessionKey] = gtServerStatus;
Session["userID"] = userID;
return geetest.getResponseStr();
}
}
}

注意:初始化结果标识status(status=1表示初始化成功,status=0表示宕机状态)需要用户保存,在后续二次验证时会取出并进行逻辑判断。本SDK demo中使用session来存取status。

二次验证(API2),包括正常流程和宕机情况

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
namespace demo
{
public partial class Validate : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void submitBtn_Click(object sender, EventArgs e)
{
GeetestLib geetest = new GeetestLib(GeetestConfig.publicKey, GeetestConfig.privateKey);
Byte gt_server_status_code = (Byte) Session[GeetestLib.gtServerStatusSessionKey];
String userID = (String) Session["userID"];
int result = 0;
String challenge = Request.Form.Get(GeetestLib.fnGeetestChallenge);
String validate = Request.Form.Get(GeetestLib.fnGeetestValidate);
String seccode = Request.Form.Get(GeetestLib.fnGeetestSeccode);

if (gt_server_status_code == 1)
result = geetest.enhencedValidateRequest(challenge, validate, seccode, userID);
else
result = geetest.failbackValidateRequest(challenge, validate, seccode);
if (result == 1)
Response.Write("<div id='sb'>success</div>");
else
Response.Write(" ");
}
}
}

注意:当取出status=0时表示极验宕机,此时流程进入failback模式,后续逻辑都是在您的服务器完成,不会再向极验服务器发送网络请求。本SDK demo中,对于failback模式,只对请求参数做了简单的校验,您也可以自行设计。

自己写的例子

前端

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/static/css/bootstrap.css">
<link rel="stylesheet" href="/static/css/mystyle.css">
</head>
<body>

<div class="container">
<div class="row">
<form class="form-horizontal col-md-6 col-md-offset-3 login-form">
{% csrf_token %}
<div class="form-group">
<label for="username" class="col-sm-2 control-label">用户名</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="username" name="username" placeholder="用户名">
<span id="user"></span>
</div>
</div>
<div class="form-group">
<label for="password" class="col-sm-2 control-label">密码</label>
<div class="col-sm-10">
<input type="password" class="form-control" id="password" name="password" placeholder="密码">
<span id="pwd"></span>
</div>
</div>
<div class="form-group">
<label for="password" class="col-sm-2 control-label">性别</label>
<div class="col-sm-10">
<select class="form-control" name="sex" id="sex">
<option value="男"></option>
<option value="女"></option>
</select>
</div>
</div>
<div class="form-group">
<!-- 放置极验的滑动验证码 -->
<div id="popup-captcha"></div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="button" class="btn btn-default" id="login-button">登录</button>
<span class="login-error"></span>
</div>
</div>
</form>
</div>
</div>

<script src="/static/js/bootstrap.js" type="text/javascript"></script>
<script src="/static/js/jquery-3.3.1.min.js"></script>
#引用人家的js
<script src="http://static.geetest.com/static/tools/gt.js"></script>

<script>

// 极验 发送登录数据的
var handlerPopup = function (captchaObj) {
// 成功的回调
captchaObj.onSuccess(function () {
var validate = captchaObj.getValidate();
// 1. 取到用户填写的用户名和密码 -> 取input框的值
var username = $("#username").val();
var password = $("#password").val();
var sex = $('#sex').val();
$.ajax({
url: "/login/", // 进行二次验证
type: "post",
dataType: "json",
data: {
username: username,
password: password,
sex: sex,
csrfmiddlewaretoken: $("[name='csrfmiddlewaretoken']").val(),
geetest_challenge: validate.geetest_challenge,
geetest_validate: validate.geetest_validate,
geetest_seccode: validate.geetest_seccode
},
success: function (data) {
console.log(data);
if (data.status) {
// 有错误,在页面上提示
$(".login-error").text(data.msg);
$.each(data.obj,function(index,value){
console.log(index,value);
var tag = document.createElement('span');
tag.innerHTML = value[0];
tag.className = 'c1';
tag.style.color = 'red';
$('.row').find('input[name="'+ index +'"]').after(tag);
})
} else {
// 登陆成功
location.href = data.msg;
}
}
});
});

$("#login-button").click(function () {
captchaObj.show();
$('.c1').remove()
});
// 将验证码加到id为captcha的元素里
captchaObj.appendTo("#popup-captcha");
// 更多接口参考:http://www.geetest.com/install/sections/idx-client-sdk.html
};
// 当input框获取焦点时将之前的错误清空
$("#username,#password").focus(function () {
// 将之前的错误清空
$(".login-error").text("");
});

// 验证开始需要向网站主后台获取id,challenge,success(是否启用failback)
$.ajax({
url: "/pc-geetest/register?t=" + (new Date()).getTime(), // 加随机数防止缓存
type: "get",
dataType: "json",
success: function (data) {
// 使用initGeetest接口
// 参数1:配置参数
// 参数2:回调,回调的第一个参数验证码对象,之后可以使用它做appendTo之类的事件
initGeetest({
gt: data.gt,
challenge: data.challenge,
product: "popup", // 产品形式,包括:float,embed,popup。注意只对PC版验证码有效
offline: !data.success // 表示用户后台检测极验服务器是否宕机,一般不需要关注
// 更多配置参数请参见:http://www.geetest.com/install/sections/idx-client-sdk.html#config
}, handlerPopup);
}
})


</script>
</body>
</html>

后端

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
from django.shortcuts import render,HttpResponse,redirect
from webapp01 import models
from django.forms import Form
from django.forms import fields
from django.http import JsonResponse
from geetest import GeetestLib

class MyForm(Form):
username = fields.CharField(required=True, error_messages={
'required': '用户名不能为空'
})
password = fields.CharField(required=True, error_messages={
'required': '密码不能为空'
})

def login(request):
if request.method == 'POST':
ret = {"status": 0, "msg": "", "obj": ""}
username = request.POST.get('username')
password = request.POST.get('password')
sex = request.POST.get('sex')
# 获取极验 滑动验证码相关的参数
gt = GeetestLib(pc_geetest_id, pc_geetest_key)
challenge = request.POST.get(gt.FN_CHALLENGE, '')
validate = request.POST.get(gt.FN_VALIDATE, '')
seccode = request.POST.get(gt.FN_SECCODE, '')
status = request.session[gt.GT_STATUS_SESSION_KEY]
user_id = request.session["user_id"]

obj = MyForm(request.POST)
if status:
result = gt.success_validate(challenge, validate, seccode, user_id)
else:
result = gt.failback_validate(challenge, validate, seccode)
if result:
if obj.is_valid():
if sex == '男':
obj = models.Man.objects.filter(username=username, password=password).first()
else:
obj = models.Woman.objects.filter(username=username, password=password).first()
if not obj:
# 用户名密码错误
ret["status"] = 1
ret["msg"] = "用户名或密码错误!"
else:
request.session['username'] = obj.username
request.session['password'] = obj.password
request.session['sex'] = obj.sex
ret["msg"] = "/index/"
else:
ret["status"] = 1
ret["obj"] = obj.errors
else:
ret["status"] = 1
ret["msg"] = "验证码错误"
return JsonResponse(ret)
return render(request, 'login.html')


pc_geetest_id = "b46d1900d0a894591916ea94ea91bd2c"
pc_geetest_key = "36fc3fe98530eea08dfc6ce76e3d24c4"

#处理极验 获取验证码的视图
def get_geetest(request):
user_id = 'test'
gt = GeetestLib(pc_geetest_id, pc_geetest_key)
status = gt.pre_process(user_id)
request.session[gt.GT_STATUS_SESSION_KEY] = status
request.session["user_id"] = user_id
response_str = gt.get_response_str()
return HttpResponse(response_str)