geetest极验验证-java使用笔记

 

业务场景

在系统业务中,需要想客户发送手机验证码,进行验证后,才能提交。但为了防止不正当的短信发送(攻击,恶意操作等),需要在发送短信前添加一个行为验证(这里使用的是 极验);

参考文档:

极验行为验证文档:https://docs.geetest.com/install/overview/start/

极验demo:https://www.geetest.com/demo/

步骤:

geetest极验验证-java使用笔记

这里参考下 官方流程,前面的注册验证就不说了,直接重点

搭建geetest的后台

首先从Github: gt3-python-sdk下载.zip文件 ,用于后台搭建

  • gt3-java-sdk-master\src\sdk\GeetestLib.java  这个文件相当java中的实体类,直接放在我的domain文件下。
  • gt3-java-sdk-master\src\demo\demo1\GeetestConfig.java ,是geetest的配置文件,用来放我们在极验后台注册应用得到的captcha_id和private_key。
  • VerifyLoginServlet.java(验证) 和 StartCaptchaServlet.java(初始化),这两个文件就是两个servlet,我直接放到了我写的一个Controller里面;

geetest极验验证-java使用笔记

geetest极验验证-java使用笔记

geetest极验验证-java使用笔记


import com.jhly.common.config.GeetestConfig;
import com.jhly.common.domain.GeetestLib;
import org.activiti.engine.impl.util.json.JSONException;
import org.activiti.engine.impl.util.json.JSONObject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;

@Controller
@RequestMapping("/gt")
public class GeetestController {

    /**
     * 初始化极验
     *
     * @param request
     * @param geetestDto
     * @param random	防止缓存
     * @return
     */
    @GetMapping("/register")
    @ResponseBody
    protected void register(HttpServletRequest request,
                         HttpServletResponse response) throws ServletException, IOException {

        GeetestLib gtSdk = new GeetestLib(GeetestConfig.getGeetest_id(), GeetestConfig.getGeetest_key(),
                GeetestConfig.isnewfailback());

        String resStr = "{}";

        String userid = "test";

        //自定义参数,可选择添加
        HashMap<String, String> param = new HashMap<String, String>();
        param.put("user_id", userid); //网站用户id
        param.put("client_type", "web"); //web:电脑上的浏览器;h5:手机上的浏览器,包括移动应用内完全内置的web_view;native:通过原生SDK植入APP应用的方式
        param.put("ip_address", "127.0.0.1"); //传输用户请求验证时所携带的IP

        //进行验证预处理
        int gtServerStatus = gtSdk.preProcess(param);

        //将服务器状态设置到session中
        request.getSession().setAttribute(gtSdk.gtServerStatusSessionKey, gtServerStatus);
        //将userid设置到session中
        request.getSession().setAttribute("userid", userid);

        resStr = gtSdk.getResponseStr();

        PrintWriter out = response.getWriter();
        out.println(resStr);

    }
    /**
     * 使用post方式,返回验证结果, request表单中必须包含challenge, validate, seccode
     */
    @PostMapping("/validate")
    @ResponseBody
        protected void validate(HttpServletRequest request,
                HttpServletResponse response) throws ServletException, IOException {

            GeetestLib gtSdk = new GeetestLib(GeetestConfig.getGeetest_id(), GeetestConfig.getGeetest_key(),
                    GeetestConfig.isnewfailback());

            String challenge = request.getParameter(GeetestLib.fn_geetest_challenge);
            String validate = request.getParameter(GeetestLib.fn_geetest_validate);
            String seccode = request.getParameter(GeetestLib.fn_geetest_seccode);

            //从session中获取gt-server状态
            int gt_server_status_code = (Integer) request.getSession().getAttribute(gtSdk.gtServerStatusSessionKey);

            //从session中获取userid
            String userid = (String)request.getSession().getAttribute("userid");

            //自定义参数,可选择添加
            HashMap<String, String> param = new HashMap<String, String>();
            param.put("user_id", userid); //网站用户id
            param.put("client_type", "web"); //web:电脑上的浏览器;h5:手机上的浏览器,包括移动应用内完全内置的web_view;native:通过原生SDK植入APP应用的方式
            param.put("ip_address", "127.0.0.1"); //传输用户请求验证时所携带的IP

            int gtResult = 0;

            if (gt_server_status_code == 1) {
                //gt-server正常,向gt-server进行二次验证

                gtResult = gtSdk.enhencedValidateRequest(challenge, validate, seccode, param);
                System.out.println(gtResult);
            } else {
                // gt-server非正常情况下,进行failback模式验证

                System.out.println("failback:use your own server captcha validate");
                gtResult = gtSdk.failbackValidateRequest(challenge, validate, seccode);
                System.out.println(gtResult);
            }


            if (gtResult == 1) {
                // 验证成功
                PrintWriter out = response.getWriter();
                JSONObject data = new JSONObject();
                try {
                    data.put("status", "success");
                    data.put("version", gtSdk.getVersionInfo());
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                out.println(data.toString());
            }
            else {
                // 验证失败
                JSONObject data = new JSONObject();
                try {
                    data.put("status", "fail");
                    data.put("version", gtSdk.getVersionInfo());
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                PrintWriter out = response.getWriter();
                out.println(data.toString());
            }

        }

}

待建geetest的前端

需要用到gt.js

geetest极验验证-java使用笔记

我这里用的是 geetest 的bind类型。效果:https://www.geetest.com/demo/slide-bind.html

引入gt.js

<script src="gt.js"></script>

搭建容器,我是bind的一个btn

geetest极验验证-java使用笔记

JavaScript

<script>
    var handler = function (captchaObj) {
        captchaObj.onReady(function () {
            $("#wait").hide();
        }).onSuccess(function () {
            var result = captchaObj.getValidate();
            if (!result) {
                return alert('请完成验证');
            }
            $.ajax({
                url: '/gt/validate',
                type: 'POST',
                dataType: 'json',
                data: {
                    username: $('#username2').val(),
                    password: $('#password2').val(),
                    geetest_challenge: result.geetest_challenge,
                    geetest_validate: result.geetest_validate,
                    geetest_seccode: result.geetest_seccode
                },
                success: function (data) {
                    if (data.status === 'success') {
                        setTimeout(function () {
                            //完成后发送验证码
                            sendsms()
                            // alert('登录成功');
                        }, 1500);
                    } else if (data.status === 'fail') {
                        setTimeout(function () {
                            alert('登录失败,请完成验证');
                            captchaObj.reset();
                        }, 1500);
                    }
                }
            });
        });
        $("#hqyzm").click(function () {

            var phone = $('#bnzf-phone').val();  //获取输入的手机号码
            // $.Dialog.loading();
            var reg_phone = /^0?(13[0-9]|15[012356789]|18[0123456789]|14[57]|17[678]|170[059]|14[57]|166|19[89])[0-9]{8}$/;;
            if(!reg_phone.test(phone)){   //验证手机是否符合格式
                layer.msg("手机号格式不正确");
                return false;
            }
            // 调用之前先通过前端表单校验
            captchaObj.verify();

        })
    };


    $.ajax({
        url: "/gt/register?t=" + (new Date()).getTime(), // 加随机数防止缓存
        type: "get",
        dataType: "json",
        success: function (data) {

            // 调用 initGeetest 进行初始化
            // 参数1:配置参数
            // 参数2:回调,回调的第一个参数验证码对象,之后可以使用它调用相应的接口
            initGeetest({
                // 以下 4 个配置参数为必须,不能缺少
                gt: data.gt,
                challenge: data.challenge,
                offline: !data.success, // 表示用户后台检测极验服务器是否宕机
                new_captcha: data.new_captcha, // 用于宕机时表示是新验证码的宕机

                product: "bind", // 产品形式,包括:float,popup
                width: "300px",
                https: true


            }, handler);
        }
    });
</script>

效果:

geetest极验验证-java使用笔记