前言

最近在网上偶然看见一个验证码,觉得很有意思,于是搜了下,是使用第三方实现的,先看效果:

总体来说效果还是可以的,官方提供的SDK也比较详细,可配置性很高。在这里在简单啰嗦几句使用方式:

使用步骤

①进入官网下载sdk接口→ http://www.geetest.com/install/ ,因为小弟是做C#的,所以此处选择C#,具体选择看各位大佬所用语言决定~

②第二步,获取代码,访问红框所示地址,下载demo。

③运行Demo(src文件夹里面的GeetestSDK项目)

④移植到自己项目中

⑴先将上述src文件拷贝到本地项目根目录下面

⑵然后打开本地项目并添加现有项目,将GeetestSDK添加进来

⑶在本地项目中添加引用

⑷View中新建容器存放验证码

  1. @using (Html.BeginForm())
  2. {
  3. <div>
  4. 用户名:
  5. </div>
  6. <div>
  7. @Html.TextBoxFor(model => model.Name)
  8. </div>
  9. <div>
  10. 密码:
  11. </div>
  12. <div>
  13. @Html.PasswordFor(model => model.Age)
  14. </div>
  15. <div>
  16. 验证码:<div id="captcha"></div> @*新增的存放验证码的容器*@
  17. </div>
  18. <div>
  19. <input type="submit" value="登陆" />
  20. </div>
  21. }

界面入下图:

⑸新建一个控制器(GetcaptchaController)和分部视图(Index)用于显示请求到的页面

控制器代码

  1.      public ActionResult Index()
  2. {
  3. Response.ContentType = "application/json";
  4. Response.Write(getCaptcha());
  5. Response.End();
  6. return View();
  7. }
  8. private String getCaptcha()
  9. {
  10. GeetestLib geetest = new GeetestLib(GeetestConfig.publicKey, GeetestConfig.privateKey);
  11. String userID = "ShowTime";
  12. Byte gtServerStatus = geetest.preProcess(userID);
  13. Session[GeetestLib.gtServerStatusSessionKey] = gtServerStatus;
  14. Session["userID"] = userID;
  15. return geetest.getResponseStr();
  16. }

其中,GeetestConfig是新建的一个类,里面代码如下:

  1. public const String publicKey = "b46d1900d0a894591916ea94ea91bd2c";
  2. public const String privateKey = "36fc3fe98530eea08dfc6ce76e3d24c4";

注:需要引入此命名空间 using GeetestSDK;

Index视图里面放一个空div就行,代码如下:

  1. <!DOCTYPE html>
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5. <title></title>
  6. </head>
  7. <body>
  8. <form id="form1">
  9. <div>
  10.  
  11. </div>
  12. </form>
  13. </body>
  14. </html>

⑹使用Ajax在登录页加载分部视图Index用于显示验证码

  1.     var handler = function (captchaObj) {
  2. //将验证码加到id为captcha的元素里
  3. captchaObj.appendTo("#captcha");
  4. };
  5. //极验
  6. $.ajax({
  7. // 获取id,challenge,success(是否启用failback)
  8. url: "/Getcaptcha/Index",
  9. type: "get",
  10. dataType: "json", // 使用jsonp格式
  11. success: function (data) {
  12. // 使用initGeetest接口
  13. // 参数1:配置参数,与创建Geetest实例时接受的参数一致
  14. // 参数2:回调,回调的第一个参数验证码对象,之后可以使用它做appendTo之类的事件
  15. initGeetest({
  16. gt: data.gt,
  17. challenge: data.challenge,
  18. product: "float", // 产品形式
  19. offline: !data.success
  20. }, handler);
  21. }
  22. });

注:需在头部引入Jquery1.9可直接引入下面两个js

  1. <script src="http://libs.baidu.com/jquery/1.9.0/jquery.js"></script>
  2. <script src="http://static.geetest.com/static/tools/gt.js"></script>

⑺在登陆按钮中判断验证是否通过,登陆的Index代码如下:

  1.      [HttpPost]
  2. public ActionResult Index(Models.HelloModel loginModel)
  3. {
  4. GeetestLib geetest = new GeetestLib(GeetestConfig.publicKey, GeetestConfig.privateKey);
  5. Byte gt_server_status_code = (Byte)Session[GeetestLib.gtServerStatusSessionKey];
  6. String userID = (String)Session["userID"];
  7. int result = ;
  8. String challenge = Request.Form.Get(GeetestLib.fnGeetestChallenge);
  9. String validate = Request.Form.Get(GeetestLib.fnGeetestValidate);
  10. String seccode = Request.Form.Get(GeetestLib.fnGeetestSeccode);
  11. if (gt_server_status_code == ) result = geetest.enhencedValidateRequest(challenge, validate, seccode, userID);
  12. else result = geetest.failbackValidateRequest(challenge, validate, seccode);
  13. if (result == ) Response.Write("success");//返回1则表明验证通过,可跳转页面或者做其他处理
  14. else Response.Write("fail");
  15. return View();
  16. }

运行效果

另:官方Demo下载下来是使用的嵌入式的验证效果,要更改此效果,可参考客户端SDK参数来配置

链接→ http://www.geetest.com/install/sections/idx-client-sdk.html#id19

Demo下载

链接:  点我下载  密码:63pd

常规验证码

最终效果

HTML

  1. <div style="MARGIN-TOP: 12px; margin-left: 0px; width: 130px; float: left;" id="checkInputLine" class="loginFormIpt showPlaceholder">
  2. <input id="checkInput" class="loginFormCheckCodeInput" title='Please enter the contents of the right picture' tabindex="4" maxlength="5" require="True" title='验证码' placeholder="验证码" type="text" name="vcode" />
  3. </div>
  4. <!-- 请输入验证码-->
  5. &nbsp;&nbsp;
  6. <img id="checkloing" src="/Home/VCode" class="loginFormCheckCodeImg" onclick="reloadcode('/Home/VCode')" title="Can not see clearly, change one." />

Ajax 请求如下:

  1. //刷新验证码
  2. function reloadcode(srcStr) {
  3. document.getElementById("checkloing").src = srcStr + "?rand=" + Math.random();
  4. }
  5. var checkInfo = "";
  6. //检查数据
  7. function Check() {
  8. checkInfo = "";
  9. //检查不能为空的数据
  10. $("input[Require='True']").each(function (i) {
  11. var tmpName = $(this).attr("name");
  12. var strVal = $(this).val();
  13. strVal = strVal.replace(/\s/g, "")
  14. if (!strVal)
  15. checkInfo += $(this).attr("placeholder") + "不能为空。<br/>";
  16. });
  17. if (checkInfo) return false;
  18. return true;
  19. }
  20. $(function () {
  21. $("#btnLogin").click(function () {
  22. var ii = layer.load();
  23. if (!Check()) {
  24. layer.close(ii);
  25. layer.msg('' + checkInfo, function () { });
  26. return;
  27. }
  28. $("#loadingDiv").show();
  29. $.ajax({
  30. url: "/Home/Index",
  31. type: "post",
  32. data: "userName=" + $("#tbUserName").val() + "&pwd=" + $("#tbPWD").val() + "&code=" + $("#checkInput").val(),
  33. success: function (data) {
  34. debugger;
  35. if (data.Result == "0") {
  36. layer.close(ii);
  37. layer.msg('' + data.MSG);
  38. return;
  39. } else if (data.Result == "1") {
  40. layer.close(ii);
  41. window.location.href = "/Home/Index";
  42. }
  43. },
  44. error: function (data) {
  45. layer.close(ii);
  46. layer.msg('' + data.MSG);
  47. }
  48. });
  49. });
  50. });

其中:

  1. layer.msg('' + data.MSG); 这种弹框方式使用了layer弹出层

Home控制器里面的VCde方法就是获取到最新的验证码,代码如下:

  1. [AllowAnonymous]//跳过登陆验证
  2. public ActionResult VCode()
  3. {
  4. VerificationCodeHelper vcode = new VerificationCodeHelper();
  5. string codeStr = vcode.GetRandomCode();
  6. if (!string.IsNullOrEmpty(codeStr))
  7. {
  8. byte[] arrImg = vcode.GetVCode(codeStr);
  9. Session["code"] = codeStr;
  10. return File(arrImg, "image/gif");
  11. }
  12. else
  13. {
  14. return RedirectToAction("/Login/VCode?rand=" + Guid.NewGuid().ToString().Substring(, ), "image/jpeg");
  15. }
  16. }

其中 VerificationCodeHelper  就是封装好的 生成验证码的类,直接使用就行,代码如下:

  1. public class VerificationCodeHelper
  2. {
  3. private static Color BackColor = Color.White;
  4. private static int Width = ;
  5. private static int Height = ;
  6. private Random _random;
  7. // private string _code;
  8.  
  9. private int _brushNameIndex;
  10.  
  11. public byte[] GetVCode(string codeStr)
  12. {
  13. _random = new Random();
  14. using (Bitmap img = new Bitmap(Width, Height))
  15. {
  16. // _code = GetRandomCode();
  17. // System.Web.HttpContext.Current.Session["vcode"] = _code;
  18. using (Graphics g = Graphics.FromImage(img))
  19. {
  20. g.Clear(Color.White);//绘画背景颜色
  21.  
  22. Paint_Text(g, codeStr);// 绘画文字
  23. // g.DrawString(strCode, new Font("微软雅黑", 15), Brushes.Blue, new PointF(5, 2));// 绘画文字
  24. Paint_TextStain(img);// 绘画噪音点
  25. g.DrawRectangle(Pens.DarkGray, , , Width - , Height - );//绘画边框
  26. using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
  27. {
  28. //将图片 保存到内存流中
  29. img.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
  30. //将内存流 里的 数据 转成 byte 数组 返回
  31. return ms.ToArray();
  32. }
  33. }
  34. }
  35.  
  36. }
  37.  
  38. /// <summary>
  39. /// 绘画文字
  40. /// </summary>
  41. /// <param name="g"></param>
  42. private void Paint_Text(Graphics g, string code)
  43. {
  44. g.DrawString(code, GetFont(), GetBrush(), , );
  45. }
  46.  
  47. /// <summary>
  48. /// 绘画文字噪音点
  49. /// </summary>
  50. /// <param name="g"></param>
  51. private void Paint_TextStain(Bitmap b)
  52. {
  53. string[] BrushName = new string[] { "OliveDrab",
  54. "ForestGreen",
  55. "DarkCyan",
  56. "LightSlateGray",
  57. "RoyalBlue",
  58. "SlateBlue",
  59. "DarkViolet",
  60. "MediumVioletRed",
  61. "IndianRed",
  62. "Firebrick",
  63. "Chocolate",
  64. "Peru",
  65. " enrod"
  66. };
  67.  
  68. for (int n = ; n < ; n++)
  69. {
  70. int x = _random.Next(Width);
  71. int y = _random.Next(Height);
  72. b.SetPixel(x, y, Color.FromName(BrushName[_brushNameIndex]));
  73.  
  74. }
  75.  
  76. }
  77. /// <summary>
  78. /// 随机取一个字体
  79. /// </summary>
  80. /// <returns></returns>
  81. private Font GetFont()
  82. {
  83. string[] FontItems = new string[]{ "Arial",
  84. "Helvetica",
  85. "Geneva",
  86. "sans-serif",
  87. "Verdana"
  88. };
  89.  
  90. int fontIndex = _random.Next(, FontItems.Length);
  91. FontStyle fontStyle = GetFontStyle(_random.Next(, ));
  92. return new Font(FontItems[fontIndex], , fontStyle);
  93. }
  94. /**/
  95. /**/
  96. /**/
  97. /// <summary>
  98. /// 随机取一个笔刷
  99. /// </summary>
  100. /// <returns></returns>
  101. private Brush GetBrush()
  102. {
  103. Brush[] BrushItems = new Brush[]{ Brushes.OliveDrab,
  104. Brushes.ForestGreen,
  105. Brushes.DarkCyan,
  106. Brushes.LightSlateGray,
  107. Brushes.RoyalBlue,
  108. Brushes.SlateBlue,
  109. Brushes.DarkViolet,
  110. Brushes.MediumVioletRed,
  111. Brushes.IndianRed,
  112. Brushes.Firebrick,
  113. Brushes.Chocolate,
  114. Brushes.Peru,
  115. Brushes.Goldenrod
  116. };
  117.  
  118. int brushIndex = _random.Next(, BrushItems.Length);
  119. _brushNameIndex = brushIndex;
  120. return BrushItems[brushIndex];
  121. }
  122. /// <summary>
  123. /// 绘画背景颜色
  124. /// </summary>
  125. /// <param name="g"></param>
  126. private void Paint_Background(Graphics g)
  127. {
  128. g.Clear(BackColor);
  129. }
  130. /**/
  131. /**/
  132. /**/
  133. /// <summary>
  134. /// 取一个字体的样式
  135. /// </summary>
  136. /// <param name="index"></param>
  137. /// <returns></returns>
  138. private FontStyle GetFontStyle(int index)
  139. {
  140. switch (index)
  141. {
  142. case :
  143. return FontStyle.Bold;
  144. case :
  145. return FontStyle.Italic;
  146. default:
  147. return FontStyle.Regular;
  148. }
  149. }
  150.  
  151. /// <summary>
  152. /// 取得一个 4 位的随机码
  153. /// </summary>
  154. /// <returns></returns>
  155. public string GetRandomCode()
  156. {
  157. return Guid.NewGuid().ToString().Substring(, );
  158. }
  159. }

注意,初次加载页面的时候,将拿到的code存入Session中,点击登录的时候,将用户输入的验证码传入后台,进行比对验证是否和Session中的验证码相同,如果相同,则允许登录,否则,验证码错误

参考Action如下:

  1. [HttpPost]
  2. public ActionResult Index(string userName, string pwd)
  3. {
  4. try
  5. {
  6. string vccode = Request.Form["code"];
  7. if (string.IsNullOrEmpty(vccode))
  8. return Json(new { Result = "", MSG = "请填写验证码" });
  9. else
  10. {
  11. if (Session["code"] == null)
  12. return Json(new { Result = "", MSG = "验证码已过期,请点击刷新验证码" });
  13. string str = Session["code"].ToString();
  14. str = str.ToLower();
  15. vccode = vccode.ToLower();
  16. if (str != vccode)
  17. return Json(new { Result = "", MSG = "验证码填写错误!" });
  18. else
  19. {
  20. Session["code"] = null;
  21. }
  22. if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(pwd))
  23. {
  24. return Json(new { Result = "", MSG = "用户或密码没有填写" });
  25. }
  26. //查询此用户
  27. #region 查询此用户
  28. List<Models.MySqlUser> adminml = new List<Models.MySqlUser>();
  29. Models.MySqlUser admin = new Models.MySqlUser();
  30. adminml = IBCodeBll.GetModelList(userName.Trim());
  31.  
  32. if (adminml.Count > )
  33. {
  34. if (!adminml[].password.ToLower().Equals(Maticsoft.Common.DEncrypt.DESEncrypt.Encrypt2(pwd.Trim()).ToLower()))
  35. {
  36. return Json(new { Result = "", MSG = "密码错误!" });
  37. }
  38. }
  39. else
  40. {
  41. return Json(new { Result = "", MSG = "用户不在在!" });
  42. }
  43. #endregion
  44. Session["UserName"] = userName.Trim().ToString();
  45. return Json(new { Result = "", MSG = "登录成功!" });
  46. }
  47. }
  48. catch (Exception ex)
  49. {
  50.  
  51. return Json(new { Result = "", MSG = ex.Message });
  52. }
  53. }

End!

随手记_C#验证码的更多相关文章

  1. .net点选验证码实现思路分享

    哈哈好久没冒泡了,最进看见点选验证码有点意思,所以想自己写一个. 先上效果图 如果你被这个效果吸引了就请继续看下去. 贴代码前先说点思路: 1.要有一个汉字库,并按字形分类.(我在数据库里是安部首分类 ...

  2. 【探索】无形验证码 —— PoW 算力验证

    先来思考一个问题:如何写一个能消耗对方时间的程序? 消耗时间还不简单,休眠一下就可以了: Sleep(1000) 这确实消耗了时间,但并没有消耗 CPU.如果对方开了变速齿轮,这瞬间就能完成. 不过要 ...

  3. TODO:Laravel增加验证码

    TODO:Laravel增加验证码1. 先聊聊验证码是什么,有什么作用?验证码(CAPTCHA)是"Completely Automated Public Turing test to te ...

  4. PHP-解析验证码类--学习笔记

    1.开始 在 网上看到使用PHP写的ValidateCode生成验证码码类,感觉不错,特拿来分析学习一下. 2.类图 3.验证码类部分代码 3.1  定义变量 //随机因子 private $char ...

  5. WPF做12306验证码点击效果

    一.效果 和12306是一样的,运行一张图上点击多个位置,横线以上和左边框还有有边框位置不允许点击,点击按钮输出坐标集合,也就是12306登陆的时候,需要向后台传递的参数. 二.实现思路 1.获取验证 ...

  6. 零OCR基础6行代码实现C#验证码识别

    这两天因为工作需要,要到某个网站采集信息,一是要模拟登陆,二是要破解验证码,本想用第三方付费打码,但是想想网上免费的代码也挺多的,于是乎准备从网上撸点代码下来,谁知道,撸了好多个都不行,本人以前也没接 ...

  7. ASP.NET中画图形验证码

    context.Response.ContentType = "image/jpeg"; //生成随机的中文验证码 string yzm = "人口手大小多少上中下男女天 ...

  8. asp.net mvc 验证码

    效果图 验证码类 namespace QJW.VerifyCode { //用法: //public FileContentResult CreateValidate() //{ // Validat ...

  9. ecshop验证码

    <?php //仿制ecshop验证码(四位大写字母和数字.背景) //处理码值(四位大写字母和数字组成) //所有的可能的字符集合 $chars = 'ABCDEFGHIJKLMNOPQRST ...

随机推荐

  1. Be Better:遇见更好的自己-2016年记

    其实并不能找到好的词语来形容过去的一年,感觉就如此平淡的过了!没有了毕业的稚气,看事情淡了,少了一丝浮躁,多了一分认真.2016也许就是那句话-多读书,多看报,少吃零食多睡觉,而我更愿意说--Be B ...

  2. NodeJs之log4js

    log4js log4js是一个管理,记录日志的工具. 其实与morgan的作用类似. 安装 npm install -g log4js log4js的6个日志级别 分别是:trace(蓝色).deb ...

  3. .NET面试题系列[8] - 泛型

    “可变性是以一种类型安全的方式,将一个对象作为另一个对象来使用.“ - Jon Skeet .NET面试题系列目录 .NET面试题系列[1] - .NET框架基础知识(1) .NET面试题系列[2] ...

  4. jQuery学习之路(6)- 简单的表格应用

    ▓▓▓▓▓▓ 大致介绍 在CSS技术之前,网页的布局基本都是依靠表格制作,当有了CSS之后,表格就被很多设计师所抛弃,但是表格也有他的用武之地,比如数据列表,下面以表格中常见的几个应用来加深对jQue ...

  5. javascript单元测试框架mochajs详解

    关于单元测试的想法 对于一些比较重要的项目,每次更新代码之后总是要自己测好久,担心一旦上线出了问题影响的服务太多,此时就希望能有一个比较规范的测试流程.在github上看到牛逼的javascript开 ...

  6. CRL快速开发框架系列教程十一(大数据分库分表解决方案)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  7. vs15 preview5 离线安装包

    1.介绍 vs15是微软打造的新一代IDE,全新的安装方式.官网介绍如下(https://blogs.msdn.microsoft.com/visualstudio/2016/10/05/announ ...

  8. python10作业思路及源码:类Fabric主机管理程序开发(仅供参考)

    类Fabric主机管理程序开发 一,作业要求 1, 运行程序列出主机组或者主机列表(已完成) 2,选择指定主机或主机组(已完成) 3,选择主机或主机组传送文件(上传/下载)(已完成) 4,充分使用多线 ...

  9. Atitit.软件研发团队建设原理与概论 理论

    Atitit.软件研发团队建设原理与概论 理论 培训 团队文化建设(内刊,ppt,书籍,杂志等) 梯队建设 技术储备人才的问题 团队建设--小红花评比. 团队建设--文化墙.doc 户外拓展 1. 团 ...

  10. OpenGL ES: Array Texture初体验

    [TOC] Array Texture这个东西的意思是,一个纹理对象,可以存储不止一张图片信息,就是说是是一个数组,每个元素都是一张图片.这样免了频繁地去切换当前需要bind的纹理,而且可以节省系统资 ...