2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > ASP.NET.MVC实现网站验证码功能

ASP.NET.MVC实现网站验证码功能

时间:2020-09-19 21:51:54

相关推荐

ASP.NET.MVC实现网站验证码功能

开发工具与关键技术:Visual Studio 生成验证码作者:孙水兵撰写时间:5月7

一、为什么网站要用到验证码

因为WEB站有时会碰到客户机恶意攻击,其中一种很常见的攻击手段就是 身份欺骗_它通过 在客户端脚本写入一些代码,然后利用其,客户机在网站,论坛反复登陆,或者攻击者创建一个HTML窗体,其窗体如果包含了你注册窗体或发帖窗体等相同的字段,然后利用"http-post"传输数据到服务器,服务器会执行相应的创建帐户,提交垃圾数据等操作,如果服务器本身不能有效验证并拒绝此非法操作,它会很严重耗费其系统资源,降低网站性能甚至使程序崩溃。(来自搜狗问问/z/q780650284.htm )

二、验证码的作用

验证码实际上是一种Web自动程序, 它有多种形式,比如手机验证码、语音验证码、视频验证码等等多种形式,主要目的还是出于对网站用户的保护,简单分类,可以有如下四个方面:

防恶意破解密码:比如百度,随便输入一个帐号,如果密码错误,马上会出现验证码防论坛灌水:这个是很常见的。有一种程序叫做顶帖机,如果无限制的刷,整个论坛可能到处是拉圾信息,比如,百度贴吧 ,你只要是新用户或者刚刚关注的贴吧,要是发帖,会马上出现验证码防止有人利用机器人进行批量注册防刷票,网上有很多投票类的网站,比如评选最美中国人(举个例子)。如果不出验证码,会有恶意的刷票行为。(来自百度经验/article/00a07f3840a93b82d028dcb9.html)

三、生成验证码的公共静态类ValidCodeUtils详解

1、创建一个公共静态类ValidCodeUtils。即另外声明一个类文件ValidCodeUtils将其改为静态类文件。

2、在公共静态类文件ValidCodeUtils中写生成随机数的方法和根据字符串创建验证码图片

产生随机数的方法getRandomCode

写一个静态类的产生随机数的方法getRandomCode,并传入一个int类型的参数(产生随机数的长度)。生命一个string类型的变量strReturn并让他为空。实例化Random产生随机数(Random 一种能够产生满足某些随机性统计要求的数字序列设备)。for循环,for循环的次数为产生随机数的长度。在for循环中,声明一个char类型的变量cRerult,然后产生一个非负随机整数并用intRandom接收。判断:如果非负随机整数intRandom除以3取余数等于0,变量cRerult为十六进制的30(十进制的48)加上非负随机整数intRandom除以10的余数并将其强制转换为char类型,以此来达到产生数字的目的。(在这里用到了ASCLL码,而在ASCLL码中,4857代表09。而任何数除以10的余数为0到9,所以十六进制的30(十进制的48)加上非负随机整数intRandom除以10的余数在十进制中的的范围为48到57,将其转换成char类型即为0到9。从而达到产生数字的目的)。如果非负随机整数intRandom除以3取余数等于1,变量cRerult为十六进制的41(十进制的65)加上非负随机整数intRandom除以十六进制的1a(十进制的26)的余数并将其强制转换为char类型(在ASCLL码中,65到97表示大写的字母A到Z,而任何数除以26的余数为0到25,因此十六进制的41(十进制的65)加上非负随机整数intRandom除以十六进制的1a(十进制的26)的取值范围为65到95,最后将其转换成将其转换成char类型即为A到Z。从而达到产生字母的目的)。如果非负随机整数intRandom除以3取余数不等于0或1。变量cRerult为十六进制的61(十进制的97)加上非负随机整数intRandom除以十六进制的1a(十进制的26)的余数并将其强制转换为char类型(在ASCLL码中, 97到122表示小写的字母a到z)。以此来达到产生小写的字母a~z的目的。在for循环外拼接变量cRerult并转换成string类型,用变量strReturn来接收拼接的变量cRerult并返回。

根据字符串创建验证码图片

创建一个数组类静态方法CreateImage,并传入一个string类型的参数strRandom(生成随机的验证码字符串)。在方法中,new一个宽为生成随机的验证码字符串*20,高为38的图片。再在绘画图面上定义一支画笔g,然后清除整个绘画图面,并以白色填充整个绘画图面。定义红色画笔。在白色绘画图面上坐标为(12,4)的地方用红色的画笔以字体为"Aril",字体大小为18来画生成验证码字符串。为防止机器,需绘制干扰线和干扰点。new一个随机类random,for循环10次,即画10条干扰线。在for循环中,要随机获取两个点的坐标,干扰线的两个端点坐标(x1,y1)、(x2,y2),从而达到绘制一条干扰线的目的。并且x轴的不能超过图片的宽度,y轴不能超过图片的高度。为防止绘制的干扰线超出图片。然后以两个端点坐标(x1,y1)、(x2,y2)绘制灰色的干扰线。和绘制干扰线类似,随机绘制100个干扰点。For循环100次随机得到100个坐标,然后在图片上以随机坐标设置颜色随机的点。绘制蓝色的矩形边框。然后就将图片保存到内存流中,然后将内存流中的内容写入byte数组中返回。

四、生成验证码的代码

HTML代码

HTML代码部分很简单,最主要的部分是在from表单中的lable标签和input标签,以及div中的img标签。Img标签中的src为:/生成验证码的action所在的控制器/控制器中生成验证码的action的名称。以此达到打开网站,页面就会显示出验证码的效果。Width为验证码图片的宽的,height为验证码图片的高度。

调用ValidCodeUtils生成验证码

在控制器中创建一个名为CreateValidCodeImage的方法。在方法中调用静态类ValidCodeUtils中的随机生成字符串的方法getRandomCode,在getRandomCode方法中传入验证码的长度(5),声明一个变量strRandom用来接收调用方法getRandomCode生成的长度为5的随机字符串。在将得到的随机字符串传入ValidCodeUtils中的CreateImage方法,并将得到的随机字符串传入该方法中。将获取到的随机字符串保存到session中,用来后面判断验证码是否正确。最后将得到的验证码图片返回。

这样就可以初步显示验证码了,不过不能切换验证码。

JS代码—切换验证码

给验证码图片写一个点击事件,用post方法将验证码切换的路径(/生成验证码的action所在的控制器/控制器中生成验证码的action的名称)返回到img标签中的src中。这样每点击一次图片就会切换一次验证码。但是由于浏览器的缓存机制,当用户调用一次验证码切换的路径时,浏览器会将该路径缓存下来,当用户再次请求该路径时,缓存机制会将之前缓存的路径调用。验证码图片就不会更改。每次切换验证码后需要清理一次缓存。但是,我们不可能让用户每切换一次验证码都清理一次缓存,因此在验证码切换的路径后面拼接一个参数t,后面加上时间(以毫秒计), 每一毫秒更改一次验证码切换的路径。从而克服缓存机制的干扰。

JS代码—提交验证码

给验证码的提交按钮写一个点击事件,获取页面得到的验证码用变量validCodeImg来接收,然后判断验证码是否为null、空字符串、undefined。然后用post提交获取到的验证码。用data接收页面返回的数据,输出控制器返回的文本。

控制器代码——判断验证码是否正确

创建一个方法UserLogin并接收视图传入的验证码。声明变量returnJsonText、sessionValidCode分别用来接收返回视图的文本和从session中获取的验证码。捕获异常,获取session中的验证码,并用sessionValidCode接收。然后判断从session中获取的验证码是否与视图传入的验证码一致并且忽略大小写。如果一致,继续往下执行,反之,输出验证码错误,返回returnJsonText。

StringComparison.CurrentCultureIgnoreCase:使用区域敏感排序规则、当前区域来比较字符串,同时忽略被比较字符串的大小写。

生成验证码的类

using System;using System.Collections.Generic;using System.Drawing;using System.Drawing.Imaging;using System.IO;using System.Linq;using System.Web;namespace mon{/// <summary>/// 公共静态/// </summary>public static class ValidCodeUtils //公共静态{/// <summary>/// 获得随机字符串/// </summary>/// <param name="intLength">随机数的长度</param>/// <returns>随机数字符串</returns>public static string GetRandomCode(int intLength){/*产生数字和密码混合的随机数*/string strReturn = string.Empty;Random random = new Random();//随机数for (int i = 0; i < intLength; i++){char cRerult;int intRandom = random.Next();//产生一个非负随机整数/*根据当前随机数来确定字符串*///intRandom % 3 获取的是intRandom/3 得到的余数if (intRandom % 3 == 0){//产生数字//位数来产生数字cRerult = (char)(0x30 + (intRandom % 10));}else if (intRandom % 3 == 1){//位数产生大写字母:大写字符 65-97 A 65//68 D 25 ZcRerult = (char)(0x41 + (intRandom % 0x1a));}else{//余数为2//产生小写字母 98 -116cRerult = (char)(0x61 + (intRandom % 0x1a));}strReturn += cRerult.ToString();}return strReturn;}/// <summary>/// 根据字符串创建验证码图片 /// </summary>/// <param name="strRandom">字符串</param>/// <returns>图片的二进制数组</returns>public static byte[] CreateImage(string strRandom){//新增图片Bitmap newBitmap = new Bitmap(strRandom.Length * 20, 38);Graphics g = Graphics.FromImage(newBitmap);g.Clear(Color.White);//在图片上绘制文字SolidBrush solidBrush = new SolidBrush(Color.Red);g.DrawString(strRandom, new Font("Aril", 18), solidBrush, 12, 4);//在图片上绘制干扰线Random random = new Random();for (int i = 0; i < 10; i++){//产生一条线,并绘制到画布。 起始点(x,y) 总结点int x1 = random.Next(newBitmap.Width);int y1 = random.Next(newBitmap.Height);int x2 = random.Next(newBitmap.Width);int y2 = random.Next(newBitmap.Height);g.DrawLine(new Pen(Color.DarkGray), x1, y1, x2, y2);}//绘制图片的前景干扰点for (int i = 0; i < 100; i++){int x = random.Next(newBitmap.Width);int y = random.Next(newBitmap.Height);newBitmap.SetPixel(x, y, Color.FromArgb(random.Next()));}//在最外边绘制边框g.DrawRectangle(new Pen(Color.Blue), 0, 0, newBitmap.Width, newBitmap.Height);g.DrawRectangle(new Pen(Color.Blue), -1, -1, newBitmap.Width, newBitmap.Height);//将图转保存到内存流中MemoryStream ms = new MemoryStream();newBitmap.Save(ms, ImageFormat.Jpeg);return ms.ToArray();//将流内容写入byte数组返回}}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。