腾讯TCaptcha滑块验证码集成

腾讯TCaptcha滑块验证码集成,主要是因为免费。参考文档https://007.qq.com/captcha/#/gettingStart

image

后台集成

在web层登录接口中添加校验逻辑,这边关键点是verifyTicket方法是怎么做校验的

1
2
3
4
5
6
7
8
9
10
11
String ip = AddressHelper.getIpAddr(request);

if(request.getMethod().toUpperCase().equals("POST")) {
// 验证码是否有效
if (!tCaptchaUtil.verifyTicket(ticket, randstr, ip)) {
apiResultEntity = PushDataUtil.setData(ConstantDefine.ApiCallResult_Code_17002, ConstantDefine.ApiCallResult_Code_17262, null);
modelAndView.setViewName("redirect:" + loginPage);
modelAndView.addObject(apiResultEntity);
return modelAndView;
}
}

编写tcaptcha.properties

1
2
3
# TCaptcha
tcaptcha.appId=xxxxxxxx
tcaptcha.appSecret=xxxxxxxx

编写TCaptchaUtil工具类在web初始化后将appid和appSecret注入到工具类中

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
public class TCaptchaUtil {
private static final Logger logger = LogManager.getLogger(TCaptchaUtil.class);

private String appId;
private String appSecret;
private OkHttpClient httpClient;
private static final String VERIFY_URL = "https://ssl.captcha.qq.com/ticket/verify?aid=%s&AppSecretKey=%s&Ticket=%s&Randstr=%s&UserIP=%s";

public TCaptchaUtil(String appId, String appSecret) {
this.appId = appId;
this.appSecret = appSecret;
this.httpClient = new OkHttpClient();
}

// 前台会将ticket和rand传过来,后台根据这个值进行验证,验证通过返回true
public boolean verifyTicket(String ticket, String rand, String userIp) {
// "https://ssl.captcha.qq.com/ticket/verify?aid=%s&AppSecretKey=%s&Ticket=%s&Randstr=%s&UserIP=%s";
HttpUrl url = new HttpUrl.Builder()
.scheme("https")
.host("ssl.captcha.qq.com")
.addPathSegment("ticket")
.addPathSegment("verify")
.addQueryParameter("aid", this.appId)
.addQueryParameter("AppSecretKey", this.appSecret)
.addQueryParameter("Ticket", ticket)
.addQueryParameter("Randstr", rand)
// .addQueryParameter("UserIP", "116.231.187.102")
.addQueryParameter("UserIP", userIp)
.build();
Request request = new Request.Builder().url(url).build();
try {
Response response = httpClient.newCall(request).execute();
if (response.code() == 200) {
JSONObject jsonResp = JSONObject.parseObject(response.body().string());
if (jsonResp.getInteger("response") == 1) {
return true;
} else {
logger.info("腾讯验证码验证失败:" + response.body().string());
}
} else {
logger.info("腾讯验证码验证失败:" + response.body().string());
}
} catch (IOException e) {
logger.catching(e);
return false;
}
return false;
}
}

在application.xml中配置TCaptcha

1
2
3
4
5
<!-- TCaptcha 配置 -->
<bean class="com.bim.bdip.cloud.home.util.TCaptchaUtil">
<constructor-arg value="${tcaptcha.appId}"/>
<constructor-arg value="${tcaptcha.appSecret}"/>
</bean>

前台集成

前台添加js <script src="https://ssl.captcha.qq.com/TCaptcha.js"></script>

用户记录临时变量数据
<input type="hidden" name="ticket" value="">
<input type="hidden" name="randstr" value="">

添加登录按钮<button id="TencentCaptcha" data-appid="xxxxxx" data-cbfn="login" class="am-btn-secondary" type="button">登录</button>

当按下回车键是触发,并生成滑块验证码

1
2
3
4
5
6
7
8
9
10
11
$(document).keyup(function(event){
if(user == "true"){
if(event.keyCode == 13){
new TencentCaptcha(
'appid',
loginCallback,
{}
).show();
}
}
});

当滑块验证码验证成功后会走回掉函数,并触发登录方法

1
2
3
4
5
window.loginCallback = function(res) {
if(res.ret === 0) {
login(res.ticket, res.randstr);
}
};

下面是真正的登录方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function login(ticket, randstr){
$("#login_form input[name='ticket']").val(ticket);
$("#login_form input[name='randstr']").val(randstr);
var identifier = $("#login_form input[name='identifier']").val().trim();
var credential = $("#login_form input[name='credential']").val().trim();


if(identifier==''){
Dialog.alert("账号不能为空!");
return;
}
if(credential==''){
Dialog.alert("密码不能为空!");
return;
}
var loginForm = $("#login_form");
loginForm.attr("action","${pageContext.request.contextPath }/user/login");
loginForm.submit();
}

腾讯TCaptcha滑块验证码集成
http://example.com/2018/09/06/2018-09-06-腾讯TCaptcha滑块验证码集成/
Author
Hoey
Posted on
September 6, 2018
Licensed under