全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

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点选验证码实现思路分享 (附demo)  # ASP.NET中画图形验证码的实现代码  # Asp.net开发之webform图片水印和图片验证码的实现方法  # asp.net登录验证码实现方法  # asp.net之生成验证码的方法集锦(一)  # 如何使用ASP.NET制作简单的验证码  # asp.net验证码图片生成示例  # ASP.NET 实现验证码以及刷新验证码的小例子  # Asp.net实现手写验证码的操作代码  # 验证码  # 个字  # 成了  # 在这个  # 令牌  # 就把  # 如图  # 其中一个  # 定了  # 小编  # 若干个  # 是在  # 鼠标  # 在此  # 微软  # 对其  # 给大家  # 作为一个  # 只需要  # 图为 


相关文章: 如何彻底删除建站之星生成的Banner?  建站之星ASP如何实现CMS高效搭建与安全管理?  北京网站制作费用多少,建立一个公司网站的费用.有哪些部分,分别要多少钱?  如何在万网主机上快速搭建网站?  如何快速搭建高效香港服务器网站?  网站制作免费,什么网站能看正片电影?  如何选择网络建站服务器?高效建站必看指南  建站之星如何通过成品分离优化网站效率?  如何制作新型网站程序文件,新型止水鱼鳞网要拆除吗?  建站一年半SEO优化实战指南:核心词挖掘与长尾流量提升策略  大型企业网站制作流程,做网站需要注册公司吗?  建站之星展会模板:智能建站与自助搭建高效解决方案  如何快速查询网址的建站时间与历史轨迹?  建站之星在线客服如何快速接入解答?  南宁网站建设制作定制,南宁网站建设可以定制吗?  网站规划与制作是什么,电子商务网站系统规划的内容及步骤是什么?  网站海报制作教学视频教程,有什么免费的高清可商用图片网站,用于海报设计?  如何制作算命网站,怎么注册算命网站?  内网网站制作软件,内网的网站如何发布到外网?  动图在线制作网站有哪些,滑动动图图集怎么做?  成都网站制作报价公司,成都工业用气开户费用?  如何选择靠谱的建站公司加盟品牌?  GML (Geography Markup Language)是什么,它如何用XML来表示地理空间信息?  济南企业网站制作公司,济南社保单位网上缴费步骤?  如何在阿里云高效完成企业建站全流程?  如何在IIS7中新建站点?详细步骤解析  建站之星如何助力企业快速打造五合一网站?  建站之星后台搭建步骤解析:模板选择与产品管理实操指南  想学网站制作怎么学,建立一个网站要花费多少?  家庭服务器如何搭建个人网站?  公司门户网站制作流程,华为官网怎么做?  如何在IIS服务器上快速部署高效网站?  制作网站的公司有哪些,做一个公司网站要多少钱?  简历在线制作网站免费版,如何创建个人简历?  如何用景安虚拟主机手机版绑定域名建站?  建站主机核心功能解析:服务器选择与网站搭建流程指南  制作网站外包平台,自动化接单网站有哪些?  ,巨量百应是干嘛的?  网站制作知乎推荐,想做自己的网站用什么工具比较好?  建站主机数据库如何配置才能提升网站性能?  如何在万网ECS上快速搭建专属网站?  C++如何编写函数模板?(泛型编程入门)  正规网站制作公司有哪些,目前国内哪家网页网站制作设计公司比较专业靠谱?口碑好?  焦点电影公司作品,电影焦点结局是什么?  建站之星代理平台如何选择最佳方案?  如何通过宝塔面板实现本地网站访问?  猪八戒网站制作视频,开发一个猪八戒网站,大约需要多少?或者自己请程序员,需要什么程序员,多少程序员能完成?  相亲简历制作网站推荐大全,新相亲大会主持人小萍萍资料?  历史网站制作软件,华为如何找回被删除的网站?  建站VPS能否同时实现高效与安全翻墙? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。