chen123gang

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

最近看滑动验证码挺火的,所以就想自己去实验做一下效果。

1.去官网申请id和key,注册进入后台

http://www.geetest.com/

 

2.配置前端页面

2.1下载js

  1 /* initGeetest 1.0.0
  2  * 用于加载id对应的验证码库,并支持宕机模式
  3  * 暴露 initGeetest 进行验证码的初始化
  4  * 一般不需要用户进行修改
  5  */
  6 var gtInit =(function (global, factory) {
  7     "use strict";
  8     if (typeof module === "object" && typeof module.exports === "object") {
  9         // CommonJS
 10         module.exports = global.document ?
 11             factory(global, true) :
 12             function (w) {
 13                 if (!w.document) {
 14                     throw new Error("Geetest requires a window with a document");
 15                 }
 16                 return factory(w);
 17             };
 18     } else {
 19         factory(global);
 20     }
 21 })(typeof window !== "undefined" ? window : this, function (window, noGlobal) {
 22     "use strict";
 23     if (typeof window === 'undefined') {
 24         throw new Error('Geetest requires browser environment');
 25     }
 26     var document = window.document;
 27     var Math = window.Math;
 28     var head = document.getElementsByTagName("head")[0];
 29 
 30     function _Object(obj) {
 31         this._obj = obj;
 32     }
 33 
 34     _Object.prototype = {
 35         _each: function (process) {
 36             var _obj = this._obj;
 37             for (var k in _obj) {
 38                 if (_obj.hasOwnProperty(k)) {
 39                     process(k, _obj[k]);
 40                 }
 41             }
 42             return this;
 43         }
 44     };
 45     function Config(config) {
 46         var self = this;
 47         new _Object(config)._each(function (key, value) {
 48             self[key] = value;
 49         });
 50     }
 51 
 52     Config.prototype = {
 53         api_server: 'api.geetest.com',
 54         protocol: 'http://',
 55         type_path: '/gettype.php',
 56         fallback_config: {
 57             slide: {
 58                 static_servers: ["static.geetest.com", "dn-staticdown.qbox.me"],
 59                 type: 'slide',
 60                 slide: '/static/js/geetest.0.0.0.js'
 61             },
 62             fullpage: {
 63                 static_servers: ["static.geetest.com", "dn-staticdown.qbox.me"],
 64                 type: 'fullpage',
 65                 fullpage: '/static/js/fullpage.0.0.0.js'
 66             }
 67         },
 68         _get_fallback_config: function () {
 69             var self = this;
 70             if (isString(self.type)) {
 71                 return self.fallback_config[self.type];
 72             } else if (self.new_captcha) {
 73                 return self.fallback_config.fullpage;
 74             } else {
 75                 return self.fallback_config.slide;
 76             }
 77         },
 78         _extend: function (obj) {
 79             var self = this;
 80             new _Object(obj)._each(function (key, value) {
 81                 self[key] = value;
 82             })
 83         }
 84     };
 85     var isNumber = function (value) {
 86         return (typeof value === 'number');
 87     };
 88     var isString = function (value) {
 89         return (typeof value === 'string');
 90     };
 91     var isBoolean = function (value) {
 92         return (typeof value === 'boolean');
 93     };
 94     var isObject = function (value) {
 95         return (typeof value === 'object' && value !== null);
 96     };
 97     var isFunction = function (value) {
 98         return (typeof value === 'function');
 99     };
100     var callbacks = {};
101     var status = {};
102     var random = function () {
103         return parseInt(Math.random() * 10000) + (new Date()).valueOf();
104     };
105     var loadScript = function (url, cb) {
106         var script = document.createElement("script");
107         script.charset = "UTF-8";
108         script.async = true;
109         script.onerror = function () {
110             cb(true);
111         };
112         var loaded = false;
113         script.onload = script.onreadystatechange = function () {
114             if (!loaded &&
115                 (!script.readyState ||
116                 "loaded" === script.readyState ||
117                 "complete" === script.readyState)) {
118 
119                 loaded = true;
120                 setTimeout(function () {
121                     cb(false);
122                 }, 0);
123             }
124         };
125         script.src = url;
126         head.appendChild(script);
127     };
128     var normalizeDomain = function (domain) {
129         return domain.replace(/^https?:\/\/|\/$/g, '');
130     };
131     var normalizePath = function (path) {
132         path = path.replace(/\/+/g, '/');
133         if (path.indexOf('/') !== 0) {
134             path = '/' + path;
135         }
136         return path;
137     };
138     var normalizeQuery = function (query) {
139         if (!query) {
140             return '';
141         }
142         var q = '?';
143         new _Object(query)._each(function (key, value) {
144             if (isString(value) || isNumber(value) || isBoolean(value)) {
145                 q = q + encodeURIComponent(key) + '=' + encodeURIComponent(value) + '&';
146             }
147         });
148         if (q === '?') {
149             q = '';
150         }
151         return q.replace(/&$/, '');
152     };
153     var makeURL = function (protocol, domain, path, query) {
154         domain = normalizeDomain(domain);
155 
156         var url = normalizePath(path) + normalizeQuery(query);
157         if (domain) {
158             url = protocol + domain + url;
159         }
160 
161         return url;
162     };
163     var load = function (protocol, domains, path, query, cb) {
164         var tryRequest = function (at) {
165 
166             var url = makeURL(protocol, domains[at], path, query);
167             loadScript(url, function (err) {
168                 if (err) {
169                     if (at >= domains.length - 1) {
170                         cb(true);
171                     } else {
172                         tryRequest(at + 1);
173                     }
174                 } else {
175                     cb(false);
176                 }
177             });
178         };
179         tryRequest(0);
180     };
181     var jsonp = function (domains, path, config, callback) {
182         if (isObject(config.getLib)) {
183             config._extend(config.getLib);
184             callback(config);
185             return;
186         }
187         if (config.offline) {
188             callback(config._get_fallback_config());
189             return;
190         }
191         var cb = "geetest_" + random();
192         window[cb] = function (data) {
193             if (data.status === 'success') {
194                 callback(data.data);
195             } else if (!data.status) {
196                 callback(data);
197             } else {
198                 callback(config._get_fallback_config());
199             }
200             window[cb] = undefined;
201             try {
202                 delete window[cb];
203             } catch (e) {
204             }
205         };
206         load(config.protocol, domains, path, {
207             gt: config.gt,
208             callback: cb
209         }, function (err) {
210             if (err) {
211                 callback(config._get_fallback_config());
212             }
213         });
214     };
215     var throwError = function (errorType, config) {
216         var errors = {
217             networkError: '网络错误'
218         };
219         if (typeof config.onError === 'function') {
220             config.onError(errors[errorType]);
221         } else {
222             throw new Error(errors[errorType]);
223         }
224     };
225     var detect = function () {
226         return !!window.Geetest;
227     };
228     if (detect()) {
229         status.slide = "loaded";
230     }
231     var initGeetest = function (userConfig, callback) {
232         var config = new Config(userConfig);
233         if (userConfig.https) {
234             config.protocol = 'https://';
235         } else if (!userConfig.protocol) {
236             config.protocol = window.location.protocol + '//';
237         }
238         jsonp([config.api_server || config.apiserver], config.type_path, config, function (newConfig) {
239             var type = newConfig.type;
240             var init = function () {
241                 config._extend(newConfig);
242                 callback(new window.Geetest(config));
243             };
244             callbacks[type] = callbacks[type] || [];
245             var s = status[type] || 'init';
246             if (s === 'init') {
247                 status[type] = 'loading';
248                 callbacks[type].push(init);
249                 load(config.protocol, newConfig.static_servers || newConfig.domains, newConfig[type] || newConfig.path, null, function (err) {
250                     if (err) {
251                         status[type] = 'fail';
252                         throwError('networkError', config);
253                     } else {
254                         status[type] = 'loaded';
255                         var cbs = callbacks[type];
256                         for (var i = 0, len = cbs.length; i < len; i = i + 1) {
257                             var cb = cbs[i];
258                             if (isFunction(cb)) {
259                                 cb();
260                             }
261                         }
262                         callbacks[type] = [];
263                     }
264                 });
265             } else if (s === "loaded") {
266                 init();
267             } else if (s === "fail") {
268                 throwError('networkError', config);
269             } else if (s === "loading") {
270                 callbacks[type].push(init);
271             }
272         });
273     };
274     window.initGeetest = initGeetest;
275     return initGeetest;
276 });
277 
278 export default {
279     gtInit
280 }
View Code

2.2然后进行引用

显示验证码的地方
<el-form-item>
<div id="captcha"></div>
<el-alert
id="wait"
class="show"
title="正在加载验证码......"
type="success">
</el-alert>
</el-form-item>
 
import gtInit from '../common/js/gt'
定义三个参数用来后续传到服务器进行验证
geetest_challenge:'',
geetest_validate:'',
geetest_seccode:'',
 
2.3定义一个方法用来初始化
 1  handleInit(){
 2         let _this=this;
 3         api.getCaptcha().then(res => {
 4            let { msg, code, data } = res;
 5             window.initGeetest({
 6                 gt: data.gt,
 7                 challenge: data.challenge,
 8                 width:"340px",
 9                 product: "embed", // 产品形式,包括:float,embed,popup。注意只对PC版验证码有效
10                 offline: !data.success, // 表示用户后台检测极验服务器是否宕机,一般不需要关注
11                 new_captcha: data.new_captcha
12             }, function(catchaObj){
13               catchaObj.appendTo("#captcha");
14               catchaObj.onReady(function(){
15                 document.getElementById('wait').style.display='none';
16               });
17               catchaObj.onSuccess(function(){
18                   _this.geetest_challenge=document.getElementsByTagName('input')['geetest_challenge'].value;
19                   _this.geetest_validate=document.getElementsByTagName('input')['geetest_validate'].value;
20                   _this.geetest_seccode=document.getElementsByTagName('input')['geetest_seccode'].value;
21               });
22               catchaObj.onError(function(){
23                 console.log('出错啦,请稍后重试');
24               })
25             })
26         });
27       },
View Code
api.getCaptcha()调用的接口
API.get('/login/getCaptcha?t='+(new Date()).getTime(), params)

2.4调用

created(){
this.handleInit();
}
 
服务器控制器接口
 1  [Route("login")]
 2     public class LoginController: ApiController
 3     {
 4         private IOptions<RecordAccountGeetestOption> _geetestOptions;
 5         private ILoggerFactory _loggerFactory;
 6         private readonly ILoginService _loginService;
 7         public LoginController(ILoginService loginService, IOptions<RecordAccountGeetestOption> geetestOptions, ILoggerFactory loggerFactory)
 8         {
 9             _loginService = loginService;
10             _geetestOptions = geetestOptions;
11             _loggerFactory = loggerFactory;
12         }
13 
14         /// <summary>
15         ///用户登陆
16         /// </summary>
17         /// <returns></returns>
18         [HttpPost, Route("index")]
19         [NoToken]
20         [ProducesResponseType(typeof(ResponseObjectExtension.ResponseObject<bool>), (int)HttpStatusCode.OK)]
21         public async Task<HttpResponseMessage> IndexAsync([FromBody]LoginRequestDto req)
22         {
23             var  validateCode = await ValidateCaptcha(req.GeetestChallenge, req.GeetestValidate, req.GeetestSeccode);
24             if (validateCode == 1)
25             {
26                 var user = await _loginService.LoginValidateAsync(req);
27                 if (user != null)
28                 {
29                     var userSession = new CurrentUser
30                     {
31                         Id = user.Id,
32                         Name = user.UserName
33                     };
34                     var token = Guid.NewGuid().ToString("N");
35                     RedisHelper.Set(token, userSession, TimeSpan.FromMinutes(60));
36                     return this.Success(token);
37                 }
38                 return this.Error(ErrCodeCommon.LoginError);
39             }
40             else
41                 return this.Error(ErrCodeCommon.ValidateCodeErr);
42         }
43 
44         /// <summary>
45         /// 二次进行验证码验证
46         /// </summary>
47         /// <param name="geetestChallenge">本次验证会话的唯一标识</param>
48         /// <param name="geetestValidate">拖动完成后server端返回的验证结果标识字符串</param>
49         /// <param name="geetestSeccode">验证结果的校验码,如果gt-server返回的不与这个值相等则表明验证失败</param>
50         /// <returns></returns>
51         public async Task<int> ValidateCaptcha(string geetestChallenge,string geetestValidate,string geetestSeccode)
52         {
53             GeetestLib geetest = new GeetestLib(_geetestOptions, _loggerFactory);
54             Byte gt_server_status_code = RedisHelper.Get<Byte>(GeetestLib.gtServerStatusSessionKey);
55             string userID = RedisHelper.Get("captchaUserID").ToString();
56             string challenge = geetestChallenge;
57             string validate =geetestValidate;
58             string seccode = geetestSeccode;
59             int res = 0;
60             if (gt_server_status_code == 1)
61                 res = await geetest.enhencedValidateRequest(challenge, validate, seccode, userID);
62             else
63                 res = geetest.failbackValidateRequest(challenge, validate, seccode);
64             return res;
65         }
66         /// <summary>
67         /// 获取验证码
68         /// </summary>
69         /// <returns></returns>
70         [HttpGet, Route("getCaptcha")]
71         public async Task<HttpResponseMessage> getCaptcha()
72         {
73             GeetestLib geetest = new GeetestLib(_geetestOptions, _loggerFactory);
74             string userID = Guid.NewGuid().ToString("N");
75             //验证初始化预处理  判断极验服务器是否宕机
76             Byte gtServerStatus = await geetest.preProcess(userID, "web", _geetestOptions.Value.IpAddress);
77             //进行存储
78             RedisHelper.Set("captchaUserID", userID, TimeSpan.FromMinutes(3));
79             RedisHelper.Set(GeetestLib.gtServerStatusSessionKey, gtServerStatus, TimeSpan.FromMinutes(3));
80             return this.Success(JsonConvert.DeserializeObject<GeetestResponseHelper>(geetest.getResponseStr()));
81         }
82     }
View Code

下面的是涉及到的一些实体和注册

 public class RecordAccountGeetestOption: GeetestOptions
     {
         public string IpAddress { get; set; }
     }
在startUp.cs注册
services.Configure<RecordAccountGeetestOption>(Configuration.GetSection(nameof(RecordAccountGeetestOption)));

appsettings.json

  "RecordAccountGeetestOption": {
    "Id": "",
    "Key": "",
    "IpAddress": "localhost"
  },

 

 

posted on 2018-09-18 16:59  chen123gang  阅读(1050)  评论(0编辑  收藏  举报