使用極驗【行爲驗證】實現人機交互驗證

官網:https://docs.geetest.com/sensebot/apirefer/api/web

流程與原理

待補充……

方法

1.引入極驗js,調用初始化方法


require("~/plugins/geetest.js");
this.handleGtInit();

2.先和服務端進行一次驗證,驗證後返回相關信息,帶着相關信息進行二次驗證

handleGtInit(status) {
				let _this = this;
				this.gtLoadStatus = true;
				this.getGtInit().then(res => {
					_this.gt_server_status = res.gt_server_status;
					window.initGeetest(
							{
								gt: res.gt,
								challenge: res.challenge,
								width: "100%",
								product: "embed", // 產品形式,包括:float,embed,popup。注意只對PC版驗證碼有效
								offline: !res.success, // 表示用戶後臺檢測極驗服務器是否宕機,一般不需要關注
								new_captcha: true
							},
							function (catchaObj) {
								catchaObj.appendTo("#captcha");
								catchaObj.onReady(function () {
									if (status === "1") {
										_this.waitShow = false;
									}
									this.gtLoadStatus = false;
								});
								catchaObj.onSuccess(function () {
									_this.geetest_challenge = catchaObj.getValidate().geetest_challenge;
									_this.geetest_validate = catchaObj.getValidate().geetest_validate;
									_this.geetest_seccode = catchaObj.getValidate().geetest_seccode;
									if (_this.checkTelephone()) {
										_this.SecondCheckGt().then(res => {
											if (res.code === 200) {
												_this.dragSuccess = true; // 必須用_this, 否則在這裏做的對於this的改變無效
												_this.showErrTips = false;
											} else {
												_this.msg = "出錯啦,請稍後重試";
												_this.showPop = true;
											}
										});
									} else {
										_this.reLoadGtCode();
										return;
									}
								});
								catchaObj.onError(function () {
									this.msg = "出錯啦,請稍後重試";
									this.showPop = true;
								});
							}
					);
				});
			},

			async getGtInit() {
				let info = {};
				await getGtInitInfo(this).then(res => {
					let {code, message} = res;
					if (code !== 200) {
						this.this.showErrTips = true;
						this.errMessage = message;
					} else {
						info = res.data;
					}
				});
				return info;
			},

3.重置驗證

	reLoadGtCode() {
				document.getElementById("captcha").innerHTML = "";
				this.gtLoadStatus = false;
				this.handleGtInit();
			},

4.二次驗證

async SecondCheckGt() {
				let res = await postCheckGt(this, {
					challenge: this.geetest_challenge,
					validate: this.geetest_validate,
					seccode: this.geetest_seccode,
					gt_server_status: this.gt_server_status
				});
				let {code, message} = res;
				if (code !== 200) {
					this.this.showErrTips = true;
					this.errMessage = message;
				}
				return res;
			},

5.校驗手機號

	// 校驗手機號
			checkTelephone() {
				let phoneReg = "";
				if (this.global_num == "+86") {
					phoneReg = /^[1][3,4,5,6,7,8,9][0-9]{9}$/; // 驗證電話號碼正則
				} else {
					phoneReg = /^([0-9]+|0)$/; //手機號必須爲數字
				}
				if (!phoneReg.test(this.telephone)) {
					this.showErrTips = true;
					this.errMessage = "請輸入正確的手機號";
					return false;
				}
				return true;
			},

6.獲取手機驗證碼


			//圖形驗證碼是否正確&發送短信
			sendMessage() {
				this.newPhone = this.global_num + "-" + this.telephone;
				return postSmsCode(this, {
					phone: this.newPhone,
					smscode_type: 2, // 2爲註冊,
					geetest_challenge: this.geetest_challenge
				}).then(res => {
					let {message, code} = res;
					if (code !== 200) {
						this.showErrTips = true;
						this.errMessage = message;
						return false;
					}
					return true;
				});
			},

7.極驗封裝方法geetest.js

"v0.4.7 Geetest Inc.";

(function (window) {
    "use strict";
    if (typeof window === 'undefined') {
        throw new Error('Geetest requires browser environment');
    }

var document = window.document;
var Math = window.Math;
var head = document.getElementsByTagName("Head")[0];

function _Object(obj) {
    this._obj = obj;
}

_Object.prototype = {
    _each: function (process) {
        var _obj = this._obj;
        for (var k in _obj) {
            if (_obj.hasOwnProperty(k)) {
                process(k, _obj[k]);
            }
        }
        return this;
    }
};

function Config(config) {
    var self = this;
    new _Object(config)._each(function (key, value) {
        self[key] = value;
    });
}

Config.prototype = {
    api_server: 'api.geetest.com',
    protocol: 'https://',
    typePath: '/gettype.php',
    fallback_config: {
        slide: {
            static_servers: ["static.geetest.com", "dn-staticdown.qbox.me"],
            type: 'slide',
            slide: '/static/js/geetest.0.0.0.js'
        },
        fullpage: {
            static_servers: ["static.geetest.com", "dn-staticdown.qbox.me"],
            type: 'fullpage',
            fullpage: '/static/js/fullpage.0.0.0.js'
        }
    },
    _get_fallback_config: function () {
        var self = this;
        if (isString(self.type)) {
            return self.fallback_config[self.type];
        } else if (self.new_captcha) {
            return self.fallback_config.fullpage;
        } else {
            return self.fallback_config.slide;
        }
    },
    _extend: function (obj) {
        var self = this;
        new _Object(obj)._each(function (key, value) {
            self[key] = value;
        })
    }
};
var isNumber = function (value) {
    return (typeof value === 'number');
};
var isString = function (value) {
    return (typeof value === 'string');
};
var isBoolean = function (value) {
    return (typeof value === 'boolean');
};
var isObject = function (value) {
    return (typeof value === 'object' && value !== null);
};
var isFunction = function (value) {
    return (typeof value === 'function');
};
var MOBILE = /Mobi/i.test(navigator.userAgent);
var pt = MOBILE ? 3 : 0;

var callbacks = {};
var status = {};

var nowDate = function () {
    var date = new Date();
    var year = date.getFullYear();
    var month = date.getMonth() + 1;
    var day = date.getDate();
    var hours = date.getHours();
    var minutes = date.getMinutes();
    var seconds = date.getSeconds();
  
    if (month >= 1 && month <= 9) {
      month = '0' + month;
    }
    if (day >= 0 && day <= 9) {
      day = '0' + day;
    }
    if (hours >= 0 && hours <= 9) {
      hours = '0' + hours;
    }
    if (minutes >= 0 && minutes <= 9) {
      minutes = '0' + minutes;
    }
    if (seconds >= 0 && seconds <= 9) {
      seconds = '0' + seconds;
    }
    var currentdate = year + '-' + month + '-' + day + " " + hours + ":" + minutes + ":" + seconds;
    return currentdate;
}

var random = function () {
    return parseInt(Math.random() * 10000) + (new Date()).valueOf();
};

var loadScript = function (url, cb) {
    var script = document.createElement("script");
    script.charset = "UTF-8";
    script.async = true;

    script.onerror = function () {
        cb(true);
    };
    var loaded = false;
    script.onload = script.onreadystatechange = function () {
        if (!loaded &&
            (!script.readyState ||
            "loaded" === script.readyState ||
            "complete" === script.readyState)) {

            loaded = true;
            setTimeout(function () {
                cb(false);
            }, 0);
        }
    };
    script.src = url;
    head.appendChild(script);
};

var normalizeDomain = function (domain) {
    // special domain: uems.sysu.edu.cn/jwxt/geetest/
    // return domain.replace(/^https?:\/\/|\/.*$/g, ''); uems.sysu.edu.cn
    return domain.replace(/^https?:\/\/|\/$/g, ''); // uems.sysu.edu.cn/jwxt/geetest
};
var normalizePath = function (path) {
    path = path.replace(/\/+/g, '/');
    if (path.indexOf('/') !== 0) {
        path = '/' + path;
    }
    return path;
};
var normalizeQuery = function (query) {
    if (!query) {
        return '';
    }
    var q = '?';
    new _Object(query)._each(function (key, value) {
        if (isString(value) || isNumber(value) || isBoolean(value)) {
            q = q + encodeURIComponent(key) + '=' + encodeURIComponent(value) + '&';
        }
    });
    if (q === '?') {
        q = '';
    }
    return q.replace(/&$/, '');
};
var makeURL = function (protocol, domain, path, query) {
    domain = normalizeDomain(domain);

    var url = normalizePath(path) + normalizeQuery(query);
    if (domain) {
        url = protocol + domain + url;
    }

    return url;
};

var load = function (config, send, protocol, domains, path, query, cb) {
    var tryRequest = function (at) {

        var url = makeURL(protocol, domains[at], path, query);
        loadScript(url, function (err) {
            if (err) {
                if (at >= domains.length - 1) {
                    cb(true);
                    // report gettype error
                    if (send) {
                        config.error_code = 508;
                        var url = protocol + domains[at] + path;
                        reportError(config, url);
                    }
                } else {
                    tryRequest(at + 1);
                }
            } else {
                cb(false);
            }
        });
    };
    tryRequest(0);
};


var jsonp = function (domains, path, config, callback) {
    if (isObject(config.getLib)) {
        config._extend(config.getLib);
        callback(config);
        return;
    }
    if (config.offline) {
        callback(config._get_fallback_config());
        return;
    }

    var cb = "geetest_" + random();
    window[cb] = function (data) {
        if (data.status == 'success') {
            callback(data.data);
        } else if (!data.status) {
            callback(data);
        } else {
            callback(config._get_fallback_config());
        }
        window[cb] = undefined;
        try {
            delete window[cb];
        } catch (e) {
        }
    };
    load(config, true, config.protocol, domains, path, {
        gt: config.gt,
        callback: cb
    }, function (err) {
        if (err) {
            callback(config._get_fallback_config());
        }
    });
};

var reportError = function (config, url) {
    load(config, false, config.protocol, ['monitor.geetest.com'], '/monitor/send', {
        time: nowDate(),
        captcha_id: config.gt,
        challenge: config.challenge,
        pt: pt,
        exception_url: url,
        error_code: config.error_code
    }, function (err) {})
}

var throwError = function (errorType, config) {
    var errors = {
        networkError: '網絡錯誤',
        gtTypeError: 'gt字段不是字符串類型'
    };
    if (typeof config.onError === 'function') {
        config.onError(errors[errorType]);
    } else {
        throw new Error(errors[errorType]);
    }
};

var detect = function () {
    return window.Geetest || document.getElementById("gt_lib");
};

if (detect()) {
    status.slide = "loaded";
}

window.initGeetest = function (userConfig, callback) {

    var config = new Config(userConfig);

    if (userConfig.https) {
        config.protocol = 'https://';
    } else if (!userConfig.protocol) {
        config.protocol = window.location.protocol + '//';
    }

    // for KFC
    if (userConfig.gt === '050cffef4ae57b5d5e529fea9540b0d1' ||
        userConfig.gt === '3bd38408ae4af923ed36e13819b14d42') {
        config.apiserver = 'yumchina.geetest.com/'; // for old js
        config.api_server = 'yumchina.geetest.com';
    }

    if (isObject(userConfig.getType)) {
        config._extend(userConfig.getType);
    }
    jsonp([config.api_server || config.apiserver], config.typePath, config, function (newConfig) {
        var type = newConfig.type;
        var init = function () {
            config._extend(newConfig);
            callback(new window.Geetest(config));
        };

        callbacks[type] = callbacks[type] || [];
        var s = status[type] || 'init';
        if (s === 'init') {
            status[type] = 'loading';

            callbacks[type].push(init);

            load(config, true, config.protocol, newConfig.static_servers || newConfig.domains, newConfig[type] || newConfig.path, null, function (err) {
                if (err) {
                    status[type] = 'fail';
                    throwError('networkError', config);
                } else {
                    status[type] = 'loaded';
                    var cbs = callbacks[type];
                    for (var i = 0, len = cbs.length; i < len; i = i + 1) {
                        var cb = cbs[i];
                        if (isFunction(cb)) {
                            cb();
                        }
                    }
                    callbacks[type] = [];
                }
            });
        } else if (s === "loaded") {
            init();
        } else if (s === "fail") {
            throwError('networkError', config);
        } else if (s === "loading") {
            callbacks[type].push(init);
        }
    });

};


})(window);

function gtInit() {

}

export default {
    gtInit
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章