Bootstrap

Android极验验证集成【滑块+文字验证】

前言:
先复制一段官网介绍

产品介绍
极验「行为验证」是一项可以帮助你的网站与APP识别与拦截机器程序批量自动化操作的SaaS应用。它是由极验开发的新一代人机验证产品,它不基于传统“问题-答案”的检测模式,而是通过利用深度学习对验证过程中产生的行为数据进行高维分析,发现人机行为模式与行为特征的差异,更加精准地区分人机行为。

使用场景
使用场景网站和APP,在所有可能被机器行为攻击的场景,例如但不限于注册、登录、短信接口、查询接口、营销活动、发帖评论等等,都可以部署使用「行为验证」,来抵御机器批量操作。

网站地址:点击此处

效果图:验证模式一共分为3种
①、Bind模式

在这里插入图片描述

②、UnBind模式
在这里插入图片描述
③、一键通过模式
在这里插入图片描述

1、首先注册账号:https://www.geetest.com/Register (注:需审核才能登陆,可以不用注册直接拿Demo中的URL)

①、登录极验后台创建应用获取APPID和APPKEY,具体步骤可参照账号创建(后台配置前端不需要)

②、远程依赖集成:在app\build.gradle中添加依赖,如果想手动下载集成参考该链接:点击此处

//极验验证(兼容androidx)
implementation 'com.geetest.sensebot:sensebot:4.2.4'
//网络请求
implementation 'com.squareup.okhttp3:okhttp:3.12.0'

2、代码部分分为
①、请求类HttpUtils

public class HttpUtils {

    private static OkHttpClient okHttpClient = new OkHttpClient();
    private static String cookie = "";
    private static final String GEETEST_VALIDATE = "geetest_validate";
    private static final String GEETEST_SECCODE = "geetest_seccode";
    private static final String GEETEST_CHALLENGE = "geetest_challenge";

    /**
     * get请求
     */
    public static String requestGet(String urlString) {
        okHttpClient.followRedirects();//不让它自动重定向
        okHttpClient.followSslRedirects();//安全套接层重定向
        Request request = new Request.Builder().url(urlString).build();
        try {
            Response response = okHttpClient.newCall(request).execute();
            cookie = response.header("Set-Cookie");
            return response.body().string();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * post请求
     */
    public static String requestPost(String urlString, String postParam) {
        okHttpClient.followRedirects();
        okHttpClient.followSslRedirects();
        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");

        String params = null;
        try {
            JSONObject jsonObject = new JSONObject(postParam);
            String seccode = jsonObject.getString(GEETEST_SECCODE);
            String validate = jsonObject.getString(GEETEST_VALIDATE);
            String challenge = jsonObject.getString(GEETEST_CHALLENGE);
            params = GEETEST_VALIDATE + "=" + validate + "&" + GEETEST_SECCODE + "=" +
                    seccode + "&" + GEETEST_CHALLENGE + "=" + challenge;
        } catch (JSONException e) {
            e.printStackTrace();
        }

        RequestBody requestBody = RequestBody.create(mediaType, params);
        Request request = new Request
                .Builder()
                .post(requestBody)
                .header("Cookie", TextUtils.isEmpty(cookie) ? "" : cookie)
                .url(urlString)
                .build();
        try {
            Response response = okHttpClient.newCall(request).execute();
            return response.body().string();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}

②、配置类GeetestUtils

public class GeetestUtils {

    /**
     * api1,需替换成自己的服务器URL
     */
    private static final String bindCaptchaURL = "https://www.geetest.com/demo/gt/register-slide";
    private static final String unBindCaptchaURL = "https://www.geetest.com/demo/gt/register-click";
    private static final String OnePassCaptchaURL = "https://www.geetest.com/demo/gt/register-fullpage";
    /**
     * api2,需替换成自己的服务器URL
     */
    private static final String bindValidateURL = "https://www.geetest.com/demo/gt/validate-slide";
    private static final String unBindValidateURL = "https://www.geetest.com/demo/gt/validate-click";
    private static final String OnePassValidateURL = "https://www.geetest.com/demo/gt/validate-fullpage";


    private static GT3GeetestUtils mGt3GeetestUtils;
    private static GT3ConfigBean gt3ConfigBean;

    private static final String TAG = "GeetestUtils";

    private static String rquestCaptchaUrl, rquestValidateUrl;

    /**
     * 0 绑定 1 非绑定 2 一键通过
     *
     * @param activity 上下文
     * @param button   按钮
     * @param type     类型
     */
    public static void customVerity(Activity activity, GT3GeetestButton button, int type) {
        if (type == 1) {
            rquestCaptchaUrl = bindCaptchaURL;
            rquestValidateUrl = bindValidateURL;
        } else if (type == 2) {
            rquestCaptchaUrl = unBindCaptchaURL;
            rquestValidateUrl = unBindValidateURL;
        } else if (type == 3) {
            rquestCaptchaUrl = OnePassCaptchaURL;
            rquestValidateUrl = OnePassValidateURL;
        }
        // TODO 请在oncreate方法里初始化以获取足够手势数据来保证第一轮验证成功率
        mGt3GeetestUtils = new GT3GeetestUtils(activity);
        // 配置bean文件,也可在oncreate初始化
        gt3ConfigBean = new GT3ConfigBean();
        // 设置验证模式,1:bind,2:unbind
        int pattern = type == 3 ? type - 1 : type;//type等于3-1 type=2
        gt3ConfigBean.setPattern(pattern);
        // 设置点击灰色区域是否消失,默认不消失
        gt3ConfigBean.setCanceledOnTouchOutside(false);
        // 设置语言,如果为null则使用系统默认语言中文(TODO 若想设置语言立即生效,则init需要在setContentView之前)
//        String language ="zh";
//        String language ="en";
//        String language ="ja";
//        String language = "zh";
//        gt3ConfigBean.setLang(language);
        // 设置加载webview超时时间,单位毫秒,默认10000,仅且webview加载静态文件超时,不包括之前的http请求
        gt3ConfigBean.setTimeout(30000);
        // 设置webview请求超时(用户点选或滑动完成,前端请求后端接口),单位毫秒,默认10000
        gt3ConfigBean.setWebviewTimeout(30000);
        // 设置回调监听
        gt3ConfigBean.setListener(new GT3Listener() {

            /**
             * 验证码加载完成
             * @param duration 加载时间和版本等信息,为json格式
             */
            @Override
            public void onDialogReady(String duration) {
                Log.e(TAG, "GT3BaseListener-->onDialogReady-->" + duration);
            }

            /**
             * 图形验证结果回调
             * @param code 1为正常 0为失败
             */
            @Override
            public void onReceiveCaptchaCode(int code) {
                Log.e(TAG, "GT3BaseListener-->onReceiveCaptchaCode-->" + code);
            }

            /**
             * 自定义api2回调
             * @param result,api2请求上传参数
             */
            @Override
            public void onDialogResult(String result) {
                Log.e(TAG, "GT3BaseListener-->onDialogResult-->" + result);
                // 开启api2逻辑
                new RequestAPI2().execute(result);
            }

            /**
             * 统计信息,参考接入文档
             * @param result
             */
            @Override
            public void onStatistics(String result) {
                Log.e(TAG, "GT3BaseListener-->onStatistics-->" + result);
            }

            /**
             * 验证码被关闭
             * @param num 1 点击验证码的关闭按钮来关闭验证码, 2 点击屏幕关闭验证码, 3 点击返回键关闭验证码
             */
            @Override
            public void onClosed(int num) {
                Log.e(TAG, "GT3BaseListener-->onClosed-->" + num);

            }

            /**
             * 验证成功回调
             * @param result
             */
            @Override
            public void onSuccess(String result) {
                Log.e(TAG, "GT3BaseListener-->onSuccess-->" + result);

            }

            /**
             * 验证失败回调
             * @param errorBean 版本号,错误码,错误描述等信息
             */
            @Override
            public void onFailed(GT3ErrorBean errorBean) {
                Log.e(TAG, "GT3BaseListener-->onFailed-->" + errorBean.toString());
            }

            /**
             * 自定义api1回调
             */
            @Override
            public void onButtonClick() {
                new RequestAPI1().execute();
            }
        });
        mGt3GeetestUtils.init(gt3ConfigBean);
        if (type == 1) {
            // 开启验证
            mGt3GeetestUtils.startCustomFlow();
        } else  {
            button.setGeetestUtils(mGt3GeetestUtils);
        }
    }

    /**
     * 请求api1
     */
    static class RequestAPI1 extends AsyncTask<Void, Void, JSONObject> {

        @Override
        protected JSONObject doInBackground(Void... params) {
            // TODO 添加时间戳防止请求被缓存
            String string = HttpUtils.requestGet(rquestCaptchaUrl + "?t=" + System.currentTimeMillis());
            JSONObject jsonObject = null;
            try {
                jsonObject = new JSONObject(string);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return jsonObject;
        }

        @Override
        protected void onPostExecute(JSONObject parmas) {
            // 继续验证
            Log.i(TAG, "RequestAPI1-->onPostExecute: " + parmas);
            // SDK可识别格式为
            // {"success":1,"challenge":"06fbb267def3c3c9530d62aa2d56d018",
            // "gt":"019924a82c70bb123aae90d483087f94"}
            // 设置返回api1数据
            // TODO 将api1请求结果传入此方法,即使为null也要传入,SDK内部已处理
            gt3ConfigBean.setApi1Json(parmas);
            mGt3GeetestUtils.getGeetest();
        }
    }

    /**
     * 请求api2
     */
    static class RequestAPI2 extends AsyncTask<String, Void, String> {

        @Override
        protected String doInBackground(String... params) {
            if (!TextUtils.isEmpty(params[0])) {
                return HttpUtils.requestPost(rquestValidateUrl, params[0]);
            } else {
                return null;
            }
        }

        @Override
        protected void onPostExecute(String result) {
            Log.i(TAG, "RequestAPI2-->onPostExecute: " + result);
            if (!TextUtils.isEmpty(result)) {
                try {
                    JSONObject jsonObject = new JSONObject(result);
                    String status = jsonObject.optString("status");
                    if (TextUtils.isEmpty(status)) {
                        status = jsonObject.optString("result");
                    }
                    if ("success".equals(status)) {
                        mGt3GeetestUtils.showSuccessDialog();
                    } else {
                        mGt3GeetestUtils.showFailedDialog();
                    }
                } catch (Exception e) {
                    mGt3GeetestUtils.showFailedDialog();
                    e.printStackTrace();
                }
            } else {
                mGt3GeetestUtils.showFailedDialog();
            }
        }
    }


    /**
     * 页面关闭时释放资源
     */
    public static void onDestroy() {
        if (mGt3GeetestUtils != null) {
            mGt3GeetestUtils.destory();
            mGt3GeetestUtils = null;
        }
    }

    /**
     * 界面切换
     */
    public static void changeDialogLayout(Configuration configuration) {
        /**
         * 设置后,界面横竖屏不会关闭验证码,推荐设置
         */
        if (mGt3GeetestUtils != null) {
            mGt3GeetestUtils.changeDialogLayout();
        }
    }

}

③、使用类GeetestActivity

public class GeetestActivity extends AppCompatActivity {

    private final String TAG = "GeetestUtils";
    private GT3GeetestButton geetestBtn;
    private Button btnBind, changeBtn;
    //默认模式(false 一键通过 true UNBind模式)
    private boolean defaultModel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_geetest);
        geetestBtn = this.findViewById(R.id.geetest);
        changeBtn = this.findViewById(R.id.change_btn);
        //绑定模式
        this.findViewById(R.id.bind).setOnClickListener(v -> {
            GeetestUtils.customVerity(this, null, 1);
        });
        changeBtn.setOnClickListener(v -> {
            if (defaultModel) {
                defaultModel = false;
            } else {
                defaultModel = true;
            }
            setGeetestModel();
        });
        setGeetestModel();
    }

    /**
     * 设置moshi
     */
    private void setGeetestModel() {
        if (defaultModel) {
            //UNBind模式
            GeetestUtils.customVerity(this, geetestBtn, 2);
            changeBtn.setText("UNBind模式 《点击此处》");
        } else {
            //一键通过模式
            GeetestUtils.customVerity(this, geetestBtn, 3);
            changeBtn.setText("一键通过模式 《点击此处》");
        }
    }

    /**
     * 界面关闭时释放资源
     */
    @Override
    protected void onDestroy() {
        super.onDestroy();
        GeetestUtils.onDestroy();
    }

    /**
     * 横竖屏切换
     * 界面横竖屏不会关闭验证码,推荐设置
     */
    @Override
    public void onConfigurationChanged(@NonNull Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        GeetestUtils.changeDialogLayout(newConfig);
    }
}

布局文件就是两个基本的Button和一个SDK的按钮

<com.geetest.sdk.views.GT3GeetestButton
       android:id="@+id/btn_geetest"
       android:layout_width="300dp"
       android:layout_height="45dp" />

注意:清单文件添加Intent网络权限这里就不贴出代码了!

;