验证码校验的前世今生及心得体会

笔者在大学时,曾给学校做过网站,其中包含了用户注册登录功能。有用户注册登录,就需要有提交表单前的验证码校验。

这里需要说明的是,有些网站的登录注册一开始并不需要输入验证码,但是在用户名密码输入错误一次以上以后,验证码输入框便会弹出。这么做的动机,无疑是在大规模数量的注册登录时,前端可以将多次错误请求挡在外面。可以有效防止机器注册或登录对服务器资源的侵占。

笔者刚接下这个网站制作的工作时,才大三刚开学,对于验证码的生成与输入校验,可谓一窍不通,于是开始在网上找控件或插件,功夫不负有心人,终于找到一款封装好的.net控件,并顺利的将它集成到登录功能中。这款控件的程序集叫作Vincent.AutoAuthCode.dll。大家可以直接搜索得到。非常感谢这款插件的作者及其分享者,帮助那时的我解决了这个问题。

这款验证码插件的特点是:1.零代码量,从工具箱中直接拖拽到页面上即可

            2.自动完成验证,并在输入时即时提示

            3.多种属性,能够在一定程度内,做到验证码图片的自定义

以下是其使用方法的截图:

         

最终效果如下图:

 

 

然而在实际工作后,这款验证码插件功能出现了瓶颈:

一方面,并不是说这插件不好,而是随着知识的增长和见识的提升,我们可以考虑自己制作验证码了。当然,自己制作验证码,其自定义特性肯定比封装好的插件强很多,某些应用场景下,需要我们能够自定义各种不同的验证码,甚至在验证码中加入汉字等。

另一方面:现在的B/S结构的web应用程序,MVC逐渐成为主流,ajax请求响应数据,依靠强大的前端JS工具,我们可以将这些数据拼装成我们想要的前台展示。从性能角度来说,服务端的工作被减少很多,大部分展示工作都交给客户端来完成。在PC、移动设备及浏览器JS引擎高速发展的今天,这逐渐成为一种趋势并能有效的提高应用程序性能。

笔者了解到:现在不少论坛已经提供了验证码的制作方案,所以在此粗略的描述下验证码的制作过程:

1.生成随机数字或字母,甚至是汉字,可控制字符长度,一般长度在4-5。

2.利用生成的字符串,绘制图片,设置图片的长度宽度等参数。

3.绘制图片的噪音点,我们看到的图片中的字符总有种乱花渐欲迷人眼的感觉,就是这么做出来的。

4.绘制图片边框。

5.将绘制好的图片保存为流返回,笔者这里使用的是一般处理程序。

输出验证码图片的代码如下:

       context.Response.ClearContent();
            context.Response.ContentType = "image/Gif";

            MemoryStream ms = CreateCodeImages.CreateCodeImg(code);
            if (null != ms)
            {
                context.Response.BinaryWrite(ms.ToArray());
            }

直接在html中调用一般处理程序,即可获得验证码图片:

 这里我们自然保存了图片中的字符,将它存在服务端,用来做用户输入的校验。通常是保存在Session里。

至于memeryStream里的代码,笔者就不贴上来了,园子里的其他前辈也做了类似的工作,大家能够在其中找到绘制图片的代码。 

 

接下来就是自制验证码的调用工作,由于ajax请求涵盖了我们和服务端交互的大部分工作,所以我们使用验证码也可以封装在ajax请求里,话不多说,上代码:


/// <summary>
/// ajax调用
/// </summary>
/// <param name="options">ajax 参数</param>
/// <param name="callback">ajax success callback function</param>
/// <param name="errorCallback">ajax error callback function</param>

///<param name="checkData">验证码校验时用户的输入</param>
/// <returns type="">$.Deferred</returns>


var
ajaxWithCode = function (options, callback, errorCallback, checkData) { var def = $.Deferred(); var self = this; //校验验证码 $.ajax({ url: '/CheckCode.ashx?code=' + checkData, type: 'GET' }).done(function (result) { var res = eval('(' + result + ')'); if (res.ok) { alert("验证成功"); //our Code var defaultOptions = $.extend({ contentType: "application/json", type: "POST", dataType: "json", async: true, cache: false, error: function (e1) { if (e1.status == 44) { alert(e1.responseText); //$.messager.alert('业务异常', e1.responseText, 'error'); } else if (e1.status == 42) { alert(e1.responseText); } else if (e1.status == 0) { console.log('ajax call have canceled by user'); } else { alert('服务器异常', e1.state + ' ' + e1.responseText, 'error'); } } }, options); if (defaultOptions.data) defaultOptions.data = ko.mapping.toJSON(defaultOptions.data); else delete defaultOptions.data; var tt = $.ajax(defaultOptions).done(function (data) { if (callback) { callback(data); } }); return def; } else { alert("验证失败"); } }); };

 

我们可以自己封装一个ajax方法,将验证码的验证放在前面,如果验证码错误,便给出错误提示,并阻止提交ajax请求,效果如下:

页面没经过美化,还请各位园友海涵。但验证码的制作及使用方式已经介绍完了,有兴趣的朋友可以试试自制验证码,并添加自己的创意,比如百度的中文验证^_^

 

posted @ 2014-11-23 15:32  TinyLeon  阅读(2186)  评论(5编辑  收藏  举报