Asp.net Web Api实现图片点击式图片验证码功能
现在验证码的形式越来越丰富,今天要实现的是在点击图片中的文字来进行校验的验证码,如图
这种验证码验证是验证鼠标是否选中了图片中文字的位置,以及选择的顺序,产生验证码的时候可以提供一组底图,然后随机获取一张图片,随机选取几个字,然后把文字的顺序打乱,分别随机放到图片的一个位置上,然后记录文字的位置和顺序,验证的时候验证一下文字的位置和顺序即可
验证码图片的类
/// <summary> /// 二维码图片 /// </summary> public class VerCodePic { /// <summary> /// 图片链接 /// </summary> public string PicURL { get; set; } /// <summary> /// 第一个字位置 /// </summary> public FontPoint Font1 { get; set; } /// <summary> /// 第二个字位置 /// </summary> public FontPoint Font2 { get; set; } /// <summary> /// 第三个字位置 /// </summary> public FontPoint Font3 { get; set; } /// <summary> /// 第四个字位置 /// </summary> public FontPoint Font4 { get; set; } } /// <summary> /// 文字位置 /// </summary> public class FontPoint { public int X { get; set; } public int Y { get; set; } }
生成验证码图片验证码的方法,在这个方法中指定了生成的验证码图片中字体大小为20个像素,因为验证码底图的大小是固定的,所以就把验证码底图按照字体的大小分成了若干个网格位置,指定一个文字在图片中的位置时只需要随机获取其中一个网格即可,如果这个网格中没有指定过文字,那就把文字放到这个网格中。
提前设定网格的方法
private static ArrayList _FontPoint; public static ArrayList FontPoint { get { if (_FontPoint==null) { _FontPoint = new ArrayList(); for (int x=0;x<10;x++) { for (int y=0;y<5;y++) { _FontPoint.Add(new Models.FontPoint() { X = x * 28, Y = y * 20 }); } } } return _FontPoint; } }
我选定的验证码底图为280*100的,所以按照上边的方法将图片分成了若干个网格,在下边设定一个文字位置的时候随机选取其中一个位置,而且给每个字都设定了不一样的颜色
/// <summary> /// 根据文字和图片获取验证码图片 /// </summary> /// <param name="content"></param> /// <param name="picFileName"></param> /// <returns></returns> public static VerCodePic GetVerCodePic(string content,string picFileName,int fontSize=20) { ClassLoger.Info("FileHelper.GetVerCodePic","开始生成二维码"); Bitmap bmp = new Bitmap(picFileName); List<int> hlist = new List<int>(); VerCodePic codepic = new VerCodePic(); int i = Utils.GetRandom(0, SystemSet.FontPoint.Count - 1); codepic.Font1 = SystemSet.FontPoint[i] as FontPoint; hlist.Add(i); A: int i2 = Utils.GetRandom(0, SystemSet.FontPoint.Count - 1); if (hlist.Contains(i2)) goto A; codepic.Font2 = SystemSet.FontPoint[i2] as FontPoint; hlist.Add(i2); B: int i3 = Utils.GetRandom(0, SystemSet.FontPoint.Count - 1); if (hlist.Contains(i3)) goto B; hlist.Add(i3); codepic.Font3 = SystemSet.FontPoint[i3] as FontPoint; C: int i4 = Utils.GetRandom(0, SystemSet.FontPoint.Count - 1); if (hlist.Contains(i4)) goto C; hlist.Add(i4); codepic.Font4 = SystemSet.FontPoint[i4] as FontPoint;string fileName = (content + "-" + picFileName+"-"+i+"|"+i2+"|"+i3+"|"+i4).MD5()+Path.GetExtension(picFileName); string dir = Path.Combine(SystemSet.ResourcesPath, SystemSet.VerCodePicPath); string filePath = Path.Combine(dir, fileName); if (File.Exists(filePath)) { codepic.PicURL = string.Format("{0}/{1}/{2}", SystemSet.WebResourcesSite, SystemSet.VerCodePicPath, fileName); return codepic; } if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } Graphics g = Graphics.FromImage(bmp); Font font = new Font("微软雅黑", fontSize, GraphicsUnit.Pixel); SolidBrush sbrush = new SolidBrush(Color.Black); SolidBrush sbrush1 = new SolidBrush(Color.Peru); SolidBrush sbrush2 = new SolidBrush(Color.YellowGreen); SolidBrush sbrush3 = new SolidBrush(Color.SkyBlue); List<char> fontlist = content.ToList(); ClassLoger.Info("FileHelper.GetVerCodePic", fontlist.Count.ToString()); g.DrawString(fontlist[0].TryToString(), font, sbrush, new PointF(codepic.Font1.X, codepic.Font1.Y)); g.DrawString(fontlist[1].TryToString(), font, sbrush1, new PointF(codepic.Font2.X, codepic.Font2.Y)); g.DrawString(fontlist[2].TryToString(), font, sbrush2, new PointF(codepic.Font3.X, codepic.Font3.Y)); g.DrawString(fontlist[3].TryToString(), font, sbrush3, new PointF(codepic.Font4.X, codepic.Font4.Y)); bmp.Save(filePath, ImageFormat.Jpeg); codepic.PicURL = string.Format("{0}/{1}/{2}",SystemSet.WebResourcesSite, SystemSet.VerCodePicPath, fileName); return codepic; }
获取图片验证码的api接口,在这个接口中从成语库中随机选取了一个成语,然后随机选取了一个图片,然后调用生成图片验证码的方法,生成了图片验证码,并且把验证码对应的信息缓存在redis中,设定缓存时间,将redis的key作为一个临时令牌随同验证码返回
/// <summary> /// 获取验证码,有效时间10分钟 /// </summary> /// <returns></returns> [HttpGet] [Route("vercode")] public JsonResult<VerCodePicViewModel> VerCodePic() { JsonResult<VerCodePicViewModel> result = new JsonResult<VerCodePicViewModel>(); result.code = 1; result.msg = "OK"; try { ClassLoger.Info("VerCodePic","开始获取成语"); cy_dictBll cybll = new cy_dictBll(); IList<cy_dict> cylist = cybll.GetAllcy_dict(); ClassLoger.Info("VerCodePic", cylist.Count.ToString()); int i = Utils.GetRandom(0, cylist.Count-1); ClassLoger.Info("VerCodePic",i.ToString()); cy_dict cy = cylist[i]; ClassLoger.Info("VerCodePic成语:",cy.chengyu); VerCodePicViewModel vcvm = new VerCodePicViewModel(); string sourcePic = FileHelper.GetVerCodePicResource(); if (sourcePic.IsNull() || !File.Exists(sourcePic)) { sourcePic = @"E:\WebResources\images\VerCodePicSource\1.jpg"; } ClassLoger.Info("VerCodePic图片",sourcePic); VerCodePic codepic = FileHelper.GetVerCodePic(cy.chengyu, sourcePic); vcvm.content = cy.chengyu; vcvm.MainPic = codepic.PicURL; result.Result = vcvm; string key = cookieKey(); RedisBase.Item_Set(key, codepic); RedisBase.ExpireEntryAt(key,DateTime.Now.AddMinutes(10)); result.ResultMsg = key; } catch (Exception ex) { ClassLoger.Error("AccountController.VerCodePic",ex); result.code = -1; result.msg = "AccountController.VerCodePic发生异常:"+ex.Message; } return result; }
效果如图:
图片验证码校验接口参数结构
public class CheckPicCodeViewModel { /// <summary> /// 客户端令牌 /// </summary> public string token { get; set; } public double x1 { get; set; } public double x2 { get; set; } public double x3 { get; set; } public double x4 { get; set; } public double y1 { get; set; } public double y2 { get; set; } public double y3 { get; set; } public double y4 { get; set; } }
验证码校验接口
/// <summary> /// 校验图片验证码是否正确 /// </summary> /// <param name="piccode"></param> /// <returns></returns> [HttpPost] [Route("checkpiccode")] public async Task<IHttpActionResult> CheckPicCode([FromBody]CheckPicCodeViewModel piccode) { JsonResult<bool> result = new JsonResult<bool>(); result.code = 1; result.msg = "OK"; if (piccode == null) { result.Result = false; result.ResultMsg = "参数错误"; return Ok(result); } if (string.IsNullOrEmpty(piccode.token) || !RedisBase.ContainsKey(piccode.token)) { result.Result = false; result.ResultMsg = "验证码已过期"; return Ok(result); } result.Result = await Task.Run<bool>(() => { bool flag = false; VerCodePic codepic = RedisBase.Item_Get<VerCodePic>(piccode.token); if (Math.Abs(codepic.Font1.X - piccode.x1) > 0.5 || Math.Abs(codepic.Font1.Y - piccode.y1) > 0.5 || Math.Abs(codepic.Font2.X - piccode.x2) > 0.5 || Math.Abs(codepic.Font2.Y - piccode.y2) > 0.5 || Math.Abs(codepic.Font3.X - piccode.x3) > 0.5 || Math.Abs(codepic.Font3.Y - piccode.y3) > 0.5 || Math.Abs(codepic.Font4.X - piccode.x4) > 0.5 || Math.Abs(codepic.Font4.Y - piccode.y4) > 0.5) { flag = false; result.ResultMsg = "验证码错误"; } else { flag = true; result.ResultMsg = "验证码正确"; } return flag; }); return Ok(result); }
传入用户选中的位置和顺序,并对其进行验证。
以上所述是小编给大家介绍的Asp.net Web Api实现图片点击式图片验证码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对猪先飞网站的支持!
相关文章
- 这篇文章主要为大家详细介绍了ASP.NET购物车的实现过程,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-22
Springboot如何实现Web系统License授权认证
这篇文章主要介绍了Springboot如何实现Web系统License授权认证,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-05-28- 在开发过程中,使用Visual Studio的断点调试功能可以很方便帮我们调试发现程序存在的错误,同样Visual Studio也支持对SQL Server里面的存储过程进行调试,下面就让我们看看具体的调试方法。...2021-09-22
C#使用Http Post方式传递Json数据字符串调用Web Service
这篇文章主要为大家详细介绍了C#使用Http Post方式传递Json数据字符串调用Web Service,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25- 最近想自学PHP ,做了个验证码,但不知道怎么搞的,总出现一个如下图的小红叉,但验证码就是显示不出来,原因如下 未修改之前,出现如下错误; (1)修改步骤如下,原因如下,原因是apache权限没开, (2)点击打开php.int., 搜索extension=ph...2013-10-04
- 这篇文章主要介绍了WebStorm无法正确识别Vue3组合式API的解决方案,帮助大家更好的理解和学习使用vue框架,感兴趣的朋友可以了解下...2021-02-18
- 这篇文章主要为大家详细介绍了JS实现随机生成验证码,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-06
InterlliJ IDEA2020新建java web项目找不到Static Web的解决
这篇文章主要介绍了InterlliJ IDEA2020新建java web项目找不到Static Web的解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-09-02jQuery Real Person验证码插件防止表单自动提交
本文介绍的jQuery插件有点特殊,防自动提交表单的验证工具,就是我们经常用到的验证码工具,先给大家看看效果。效果图如下: 使用说明 需要使用jQuery库文件和Real Person库文件 同时需要自定义验证码显示的CSS样式 使用实例...2015-11-08- 这篇文章主要介绍了浅谈vue2的$refs在vue3组合式API中的替代方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-04-18
ASP.NET Core根据环境变量支持多个 appsettings.json配置文件
这篇文章主要介绍了ASP.NET Core根据环境变量支持多个 appsettings.json配置文件,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-09-22- 这篇文章主要介绍了记一次EFCore类型转换错误及解决方案,帮助大家更好的理解和学习使用asp.net core,感兴趣的朋友可以了解下...2021-09-22
详解在IDEA中将Echarts引入web两种方式(使用js文件和maven的依赖导入)
这篇文章主要介绍了在IDEA中将Echarts引入web两种方式(使用js文件和maven的依赖导入),本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-07-11- 通过jquery.cookie.js插件可以快速实现“点击获取验证码后60秒内禁止重新获取(防刷新)”的功能效果图:先到官网(http://plugins.jquery.com/cookie/)下载cookie插件,放到相应文件夹,代码如下:复制代码 代码如下: <!DOCTYPE ht...2015-03-15
- 这篇文章主要介绍了jQuery mobile 移动web(6)的相关资料,需要的朋友可以参考下...2015-12-21
- 验证码类文件 CreateImg.class.php <?php class ValidationCode { private $width,$height,$codenum; public $checkcode; //产生的验证码 private $checkimage; //验证码图片 private $disturbColor = ''; /...2015-11-08
- 这篇文章主要介绍了如何使用 JavaScript 操作浏览器历史记录 API,帮助大家更好的理解和使用JavaScript,感兴趣的朋友可以了解下...2020-11-24
- 这篇文章主要介绍了基于JavaScript实现验证码功能的相关资料...2017-04-03
- 这篇文章主要帮助大家理解JavaScript中worker事件api,对worker事件api有一个深刻了解,感兴趣的小伙伴们可以参考一下...2015-12-27
- 在日常开发中,总会接触到各种接口,前后端数据传输接口,第三方业务平台接口,下面这篇文章主要给大家介绍了关于如何设计一个安全的API接口的相关资料,需要的朋友可以参考下...2021-08-12