Asp.net web API realizes the function of picture click picture verification code

Time:2021-7-31

Now the form of verification code is more and more rich. Today, what we want to realize is the verification code to verify by clicking the text in the picture, as shown in the figure

This verification code verification is to verify whether the mouse has selected the position and order of the text in the picture. When generating the verification code, you can provide a group of base maps, then randomly obtain a picture, randomly select a few words, then disrupt the order of the text, randomly place them in a position of the picture, and then record the position and order of the text, When verifying, verify the position and order of the text

Class of verification code picture

/// <summary>
 ///QR code picture
 /// </summary>
 public class VerCodePic
 {
  /// <summary>
  ///Picture link
  /// </summary>
  public string PicURL { get; set; }
  /// <summary>
  ///First word position
  /// </summary>
  public FontPoint Font1 { get; set; }
  /// <summary>
  ///Second word position
  /// </summary>
  public FontPoint Font2 { get; set; }
  /// <summary>
  ///Third word position
  /// </summary>
  public FontPoint Font3 { get; set; }
  /// <summary>
  ///Fourth word position
  /// </summary>
  public FontPoint Font4 { get; set; }
 }
 /// <summary>
 ///Text position
 /// </summary>
 public class FontPoint
 {
  public int X { get; set; }
  public int Y { get; set; }
 }

The method of generating the verification code image verification code. In this method, the font size in the generated verification code image is specified as 20 pixels. Because the size of the verification code base map is fixed, the verification code base map is divided into several grid positions according to the font size. When specifying the position of a text in the image, only one grid needs to be obtained randomly, If no text is specified in the grid, put the text in the grid.

Method of setting grid in advance


 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;
   }
  }

The verification code base map I selected is 280 * 100, so the picture is divided into several grids according to the method above. When setting a text position at the bottom, I randomly select one of the positions, and set different colors for each word

/// <summary>
  ///Obtain the verification code image according to the text and image
  /// </summary>
  /// <param name="content"></param>
  /// <param name="picFileName"></param>
  /// <returns></returns>
  public static VerCodePic GetVerCodePic(string content,string picFileName,int fontSize=20)
  {
   Classlogger.info ("filehelper. Getvercodepic", "start generating QR code");
   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 ("Microsoft YaHei", 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;
  }

To get the API interface of the picture verification code, randomly select an idiom from the idiom Library in this interface, then randomly select a picture, then call the method of generating the image verification code, generate the image verification code, cache the corresponding information of the verification code in redis, set the cache time, and return the redis key as a temporary token with the verification code.

/// <summary>
  ///Get the verification code, valid for 10 minutes
  /// </summary>
  /// <returns></returns>
  [HttpGet]
  [Route("vercode")]
  public JsonResult<VerCodePicViewModel> VerCodePic()
  {
   JsonResult<VerCodePicViewModel> result = new JsonResult<VerCodePicViewModel>();
   result.code = 1;
   result.msg = "OK";
   try
   {
    Classlogger. Info ("vercodepic", "start getting Idioms");
    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];
    Classlogger. Info ("vercodepic idiom:", cy.chengyu);
    VerCodePicViewModel vcvm = new VerCodePicViewModel();
    string sourcePic = FileHelper.GetVerCodePicResource();
    if (sourcePic.IsNull() || !File.Exists(sourcePic))
    {
     sourcePic = @"E:\WebResources\images\VerCodePicSource.jpg";
    }
    Classlogger. Info ("vercodepic picture", 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 = "exception occurred in accountcontroller.vercodepic:" + ex.message;
   }
   return result;
  }

The effect is shown in the figure:

Picture verification code verification interface parameter structure

public class CheckPicCodeViewModel
 {
  /// <summary>
  ///Client token
  /// </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; }
 }

Verification code verification interface

/// <summary>
  ///Check whether the picture verification code is correct
  /// </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 = "parameter error";
    return Ok(result);
   }
   if (string.IsNullOrEmpty(piccode.token) || !RedisBase.ContainsKey(piccode.token))
   {
    result.Result = false;
    Result.resultmsg = "the verification code has expired";
    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 = "verification code error";
    }
    else
    {
     flag = true;
     Result.resultmsg = "the verification code is correct";
    }
    return flag;
   });
   return Ok(result);
  }

Pass in the location and order selected by the user and verify it.

The above is the asp.net web API implementation picture click picture verification code introduced by Xiaobian. I hope it will be helpful to you. If you have any questions, please leave me a message and Xiaobian will reply to you in time. Thank you very much for your support to the developeppaer website!