最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 科技 - 知识百科 - 正文

Asp.net Web Api实现图片点击式图片验证码功能

来源:懂视网 责编:小采 时间:2020-11-27 22:35:32
文档

Asp.net Web Api实现图片点击式图片验证码功能

Asp.net Web Api实现图片点击式图片验证码功能:现在验证码的形式越来越丰富,今天要实现的是在点击图片中的文字来进行校验的验证码,如图 这种验证码验证是验证鼠标是否选中了图片中文字的位置,以及选择的顺序,产生验证码的时候可以提供一组底图,然后随机获取一张图片,随机选取几个字,然后把文字的顺
推荐度:
导读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 Web Api实现图片点击式图片验证码功能

Asp.net Web Api实现图片点击式图片验证码功能:现在验证码的形式越来越丰富,今天要实现的是在点击图片中的文字来进行校验的验证码,如图 这种验证码验证是验证鼠标是否选中了图片中文字的位置,以及选择的顺序,产生验证码的时候可以提供一组底图,然后随机获取一张图片,随机选取几个字,然后把文字的顺
推荐度:
标签: 图片 验证码 实现
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top