随手记_C#验证码
前言
最近在网上偶然看见一个验证码,觉得很有意思,于是搜了下,是使用第三方实现的,先看效果:
总体来说效果还是可以的,官方提供的SDK也比较详细,可配置性很高。在这里在简单啰嗦几句使用方式:
使用步骤
①进入官网下载sdk接口→ http://www.geetest.com/install/ ,因为小弟是做C#的,所以此处选择C#,具体选择看各位大佬所用语言决定~
②第二步,获取代码,访问红框所示地址,下载demo。
③运行Demo(src文件夹里面的GeetestSDK项目)
④移植到自己项目中
⑴先将上述src文件拷贝到本地项目根目录下面
⑵然后打开本地项目并添加现有项目,将GeetestSDK添加进来
⑶在本地项目中添加引用
⑷View中新建容器存放验证码
- @using (Html.BeginForm())
- {
- <div>
- 用户名:
- </div>
- <div>
- @Html.TextBoxFor(model => model.Name)
- </div>
- <div>
- 密码:
- </div>
- <div>
- @Html.PasswordFor(model => model.Age)
- </div>
- <div>
- 验证码:<div id="captcha"></div> @*新增的存放验证码的容器*@
- </div>
- <div>
- <input type="submit" value="登陆" />
- </div>
- }
界面入下图:
⑸新建一个控制器(GetcaptchaController)和分部视图(Index)用于显示请求到的页面
控制器代码
- public ActionResult Index()
- {
- Response.ContentType = "application/json";
- Response.Write(getCaptcha());
- Response.End();
- return View();
- }
- private String getCaptcha()
- {
- GeetestLib geetest = new GeetestLib(GeetestConfig.publicKey, GeetestConfig.privateKey);
- String userID = "ShowTime";
- Byte gtServerStatus = geetest.preProcess(userID);
- Session[GeetestLib.gtServerStatusSessionKey] = gtServerStatus;
- Session["userID"] = userID;
- return geetest.getResponseStr();
- }
其中,GeetestConfig是新建的一个类,里面代码如下:
- public const String publicKey = "b46d1900d0a894591916ea94ea91bd2c";
- public const String privateKey = "36fc3fe98530eea08dfc6ce76e3d24c4";
注:需要引入此命名空间 using GeetestSDK;
Index视图里面放一个空div就行,代码如下:
- <!DOCTYPE html>
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title></title>
- </head>
- <body>
- <form id="form1">
- <div>
- </div>
- </form>
- </body>
- </html>
⑹使用Ajax在登录页加载分部视图Index用于显示验证码
- var handler = function (captchaObj) {
- //将验证码加到id为captcha的元素里
- captchaObj.appendTo("#captcha");
- };
- //极验
- $.ajax({
- // 获取id,challenge,success(是否启用failback)
- url: "/Getcaptcha/Index",
- type: "get",
- dataType: "json", // 使用jsonp格式
- success: function (data) {
- // 使用initGeetest接口
- // 参数1:配置参数,与创建Geetest实例时接受的参数一致
- // 参数2:回调,回调的第一个参数验证码对象,之后可以使用它做appendTo之类的事件
- initGeetest({
- gt: data.gt,
- challenge: data.challenge,
- product: "float", // 产品形式
- offline: !data.success
- }, handler);
- }
- });
注:需在头部引入Jquery1.9可直接引入下面两个js
- <script src="http://libs.baidu.com/jquery/1.9.0/jquery.js"></script>
- <script src="http://static.geetest.com/static/tools/gt.js"></script>
⑺在登陆按钮中判断验证是否通过,登陆的Index代码如下:
- [HttpPost]
- public ActionResult Index(Models.HelloModel loginModel)
- {
- GeetestLib geetest = new GeetestLib(GeetestConfig.publicKey, GeetestConfig.privateKey);
- Byte gt_server_status_code = (Byte)Session[GeetestLib.gtServerStatusSessionKey];
- String userID = (String)Session["userID"];
- int result = ;
- String challenge = Request.Form.Get(GeetestLib.fnGeetestChallenge);
- String validate = Request.Form.Get(GeetestLib.fnGeetestValidate);
- String seccode = Request.Form.Get(GeetestLib.fnGeetestSeccode);
- if (gt_server_status_code == ) result = geetest.enhencedValidateRequest(challenge, validate, seccode, userID);
- else result = geetest.failbackValidateRequest(challenge, validate, seccode);
- if (result == ) Response.Write("success");//返回1则表明验证通过,可跳转页面或者做其他处理
- else Response.Write("fail");
- return View();
- }
运行效果
另:官方Demo下载下来是使用的嵌入式的验证效果,要更改此效果,可参考客户端SDK参数来配置
链接→ http://www.geetest.com/install/sections/idx-client-sdk.html#id19
Demo下载
链接: 点我下载 密码:63pd
常规验证码
最终效果
HTML
- <div style="MARGIN-TOP: 12px; margin-left: 0px; width: 130px; float: left;" id="checkInputLine" class="loginFormIpt showPlaceholder">
- <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" />
- </div>
- <!-- 请输入验证码-->
-
- <img id="checkloing" src="/Home/VCode" class="loginFormCheckCodeImg" onclick="reloadcode('/Home/VCode')" title="Can not see clearly, change one." />
Ajax 请求如下:
- //刷新验证码
- function reloadcode(srcStr) {
- document.getElementById("checkloing").src = srcStr + "?rand=" + Math.random();
- }
- var checkInfo = "";
- //检查数据
- function Check() {
- checkInfo = "";
- //检查不能为空的数据
- $("input[Require='True']").each(function (i) {
- var tmpName = $(this).attr("name");
- var strVal = $(this).val();
- strVal = strVal.replace(/\s/g, "")
- if (!strVal)
- checkInfo += $(this).attr("placeholder") + "不能为空。<br/>";
- });
- if (checkInfo) return false;
- return true;
- }
- $(function () {
- $("#btnLogin").click(function () {
- var ii = layer.load();
- if (!Check()) {
- layer.close(ii);
- layer.msg('' + checkInfo, function () { });
- return;
- }
- $("#loadingDiv").show();
- $.ajax({
- url: "/Home/Index",
- type: "post",
- data: "userName=" + $("#tbUserName").val() + "&pwd=" + $("#tbPWD").val() + "&code=" + $("#checkInput").val(),
- success: function (data) {
- debugger;
- if (data.Result == "0") {
- layer.close(ii);
- layer.msg('' + data.MSG);
- return;
- } else if (data.Result == "1") {
- layer.close(ii);
- window.location.href = "/Home/Index";
- }
- },
- error: function (data) {
- layer.close(ii);
- layer.msg('' + data.MSG);
- }
- });
- });
- });
其中:
- layer.msg('' + data.MSG); 这种弹框方式使用了layer弹出层
Home控制器里面的VCde方法就是获取到最新的验证码,代码如下:
- [AllowAnonymous]//跳过登陆验证
- public ActionResult VCode()
- {
- VerificationCodeHelper vcode = new VerificationCodeHelper();
- string codeStr = vcode.GetRandomCode();
- if (!string.IsNullOrEmpty(codeStr))
- {
- byte[] arrImg = vcode.GetVCode(codeStr);
- Session["code"] = codeStr;
- return File(arrImg, "image/gif");
- }
- else
- {
- return RedirectToAction("/Login/VCode?rand=" + Guid.NewGuid().ToString().Substring(, ), "image/jpeg");
- }
- }
其中 VerificationCodeHelper 就是封装好的 生成验证码的类,直接使用就行,代码如下:
- public class VerificationCodeHelper
- {
- private static Color BackColor = Color.White;
- private static int Width = ;
- private static int Height = ;
- private Random _random;
- // private string _code;
- private int _brushNameIndex;
- public byte[] GetVCode(string codeStr)
- {
- _random = new Random();
- using (Bitmap img = new Bitmap(Width, Height))
- {
- // _code = GetRandomCode();
- // System.Web.HttpContext.Current.Session["vcode"] = _code;
- using (Graphics g = Graphics.FromImage(img))
- {
- g.Clear(Color.White);//绘画背景颜色
- Paint_Text(g, codeStr);// 绘画文字
- // g.DrawString(strCode, new Font("微软雅黑", 15), Brushes.Blue, new PointF(5, 2));// 绘画文字
- Paint_TextStain(img);// 绘画噪音点
- g.DrawRectangle(Pens.DarkGray, , , Width - , Height - );//绘画边框
- using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
- {
- //将图片 保存到内存流中
- img.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
- //将内存流 里的 数据 转成 byte 数组 返回
- return ms.ToArray();
- }
- }
- }
- }
- /// <summary>
- /// 绘画文字
- /// </summary>
- /// <param name="g"></param>
- private void Paint_Text(Graphics g, string code)
- {
- g.DrawString(code, GetFont(), GetBrush(), , );
- }
- /// <summary>
- /// 绘画文字噪音点
- /// </summary>
- /// <param name="g"></param>
- private void Paint_TextStain(Bitmap b)
- {
- string[] BrushName = new string[] { "OliveDrab",
- "ForestGreen",
- "DarkCyan",
- "LightSlateGray",
- "RoyalBlue",
- "SlateBlue",
- "DarkViolet",
- "MediumVioletRed",
- "IndianRed",
- "Firebrick",
- "Chocolate",
- "Peru",
- " enrod"
- };
- for (int n = ; n < ; n++)
- {
- int x = _random.Next(Width);
- int y = _random.Next(Height);
- b.SetPixel(x, y, Color.FromName(BrushName[_brushNameIndex]));
- }
- }
- /// <summary>
- /// 随机取一个字体
- /// </summary>
- /// <returns></returns>
- private Font GetFont()
- {
- string[] FontItems = new string[]{ "Arial",
- "Helvetica",
- "Geneva",
- "sans-serif",
- "Verdana"
- };
- int fontIndex = _random.Next(, FontItems.Length);
- FontStyle fontStyle = GetFontStyle(_random.Next(, ));
- return new Font(FontItems[fontIndex], , fontStyle);
- }
- /**/
- /**/
- /**/
- /// <summary>
- /// 随机取一个笔刷
- /// </summary>
- /// <returns></returns>
- private Brush GetBrush()
- {
- Brush[] BrushItems = new Brush[]{ Brushes.OliveDrab,
- Brushes.ForestGreen,
- Brushes.DarkCyan,
- Brushes.LightSlateGray,
- Brushes.RoyalBlue,
- Brushes.SlateBlue,
- Brushes.DarkViolet,
- Brushes.MediumVioletRed,
- Brushes.IndianRed,
- Brushes.Firebrick,
- Brushes.Chocolate,
- Brushes.Peru,
- Brushes.Goldenrod
- };
- int brushIndex = _random.Next(, BrushItems.Length);
- _brushNameIndex = brushIndex;
- return BrushItems[brushIndex];
- }
- /// <summary>
- /// 绘画背景颜色
- /// </summary>
- /// <param name="g"></param>
- private void Paint_Background(Graphics g)
- {
- g.Clear(BackColor);
- }
- /**/
- /**/
- /**/
- /// <summary>
- /// 取一个字体的样式
- /// </summary>
- /// <param name="index"></param>
- /// <returns></returns>
- private FontStyle GetFontStyle(int index)
- {
- switch (index)
- {
- case :
- return FontStyle.Bold;
- case :
- return FontStyle.Italic;
- default:
- return FontStyle.Regular;
- }
- }
- /// <summary>
- /// 取得一个 4 位的随机码
- /// </summary>
- /// <returns></returns>
- public string GetRandomCode()
- {
- return Guid.NewGuid().ToString().Substring(, );
- }
- }
注意,初次加载页面的时候,将拿到的code存入Session中,点击登录的时候,将用户输入的验证码传入后台,进行比对验证是否和Session中的验证码相同,如果相同,则允许登录,否则,验证码错误
参考Action如下:
- [HttpPost]
- public ActionResult Index(string userName, string pwd)
- {
- try
- {
- string vccode = Request.Form["code"];
- if (string.IsNullOrEmpty(vccode))
- return Json(new { Result = "", MSG = "请填写验证码" });
- else
- {
- if (Session["code"] == null)
- return Json(new { Result = "", MSG = "验证码已过期,请点击刷新验证码" });
- string str = Session["code"].ToString();
- str = str.ToLower();
- vccode = vccode.ToLower();
- if (str != vccode)
- return Json(new { Result = "", MSG = "验证码填写错误!" });
- else
- {
- Session["code"] = null;
- }
- if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(pwd))
- {
- return Json(new { Result = "", MSG = "用户或密码没有填写" });
- }
- //查询此用户
- #region 查询此用户
- List<Models.MySqlUser> adminml = new List<Models.MySqlUser>();
- Models.MySqlUser admin = new Models.MySqlUser();
- adminml = IBCodeBll.GetModelList(userName.Trim());
- if (adminml.Count > )
- {
- if (!adminml[].password.ToLower().Equals(Maticsoft.Common.DEncrypt.DESEncrypt.Encrypt2(pwd.Trim()).ToLower()))
- {
- return Json(new { Result = "", MSG = "密码错误!" });
- }
- }
- else
- {
- return Json(new { Result = "", MSG = "用户不在在!" });
- }
- #endregion
- Session["UserName"] = userName.Trim().ToString();
- return Json(new { Result = "", MSG = "登录成功!" });
- }
- }
- catch (Exception ex)
- {
- return Json(new { Result = "", MSG = ex.Message });
- }
- }
End!
随手记_C#验证码的更多相关文章
- .net点选验证码实现思路分享
哈哈好久没冒泡了,最进看见点选验证码有点意思,所以想自己写一个. 先上效果图 如果你被这个效果吸引了就请继续看下去. 贴代码前先说点思路: 1.要有一个汉字库,并按字形分类.(我在数据库里是安部首分类 ...
- 【探索】无形验证码 —— PoW 算力验证
先来思考一个问题:如何写一个能消耗对方时间的程序? 消耗时间还不简单,休眠一下就可以了: Sleep(1000) 这确实消耗了时间,但并没有消耗 CPU.如果对方开了变速齿轮,这瞬间就能完成. 不过要 ...
- TODO:Laravel增加验证码
TODO:Laravel增加验证码1. 先聊聊验证码是什么,有什么作用?验证码(CAPTCHA)是"Completely Automated Public Turing test to te ...
- PHP-解析验证码类--学习笔记
1.开始 在 网上看到使用PHP写的ValidateCode生成验证码码类,感觉不错,特拿来分析学习一下. 2.类图 3.验证码类部分代码 3.1 定义变量 //随机因子 private $char ...
- WPF做12306验证码点击效果
一.效果 和12306是一样的,运行一张图上点击多个位置,横线以上和左边框还有有边框位置不允许点击,点击按钮输出坐标集合,也就是12306登陆的时候,需要向后台传递的参数. 二.实现思路 1.获取验证 ...
- 零OCR基础6行代码实现C#验证码识别
这两天因为工作需要,要到某个网站采集信息,一是要模拟登陆,二是要破解验证码,本想用第三方付费打码,但是想想网上免费的代码也挺多的,于是乎准备从网上撸点代码下来,谁知道,撸了好多个都不行,本人以前也没接 ...
- ASP.NET中画图形验证码
context.Response.ContentType = "image/jpeg"; //生成随机的中文验证码 string yzm = "人口手大小多少上中下男女天 ...
- asp.net mvc 验证码
效果图 验证码类 namespace QJW.VerifyCode { //用法: //public FileContentResult CreateValidate() //{ // Validat ...
- ecshop验证码
<?php //仿制ecshop验证码(四位大写字母和数字.背景) //处理码值(四位大写字母和数字组成) //所有的可能的字符集合 $chars = 'ABCDEFGHIJKLMNOPQRST ...
随机推荐
- Be Better:遇见更好的自己-2016年记
其实并不能找到好的词语来形容过去的一年,感觉就如此平淡的过了!没有了毕业的稚气,看事情淡了,少了一丝浮躁,多了一分认真.2016也许就是那句话-多读书,多看报,少吃零食多睡觉,而我更愿意说--Be B ...
- NodeJs之log4js
log4js log4js是一个管理,记录日志的工具. 其实与morgan的作用类似. 安装 npm install -g log4js log4js的6个日志级别 分别是:trace(蓝色).deb ...
- .NET面试题系列[8] - 泛型
“可变性是以一种类型安全的方式,将一个对象作为另一个对象来使用.“ - Jon Skeet .NET面试题系列目录 .NET面试题系列[1] - .NET框架基础知识(1) .NET面试题系列[2] ...
- jQuery学习之路(6)- 简单的表格应用
▓▓▓▓▓▓ 大致介绍 在CSS技术之前,网页的布局基本都是依靠表格制作,当有了CSS之后,表格就被很多设计师所抛弃,但是表格也有他的用武之地,比如数据列表,下面以表格中常见的几个应用来加深对jQue ...
- javascript单元测试框架mochajs详解
关于单元测试的想法 对于一些比较重要的项目,每次更新代码之后总是要自己测好久,担心一旦上线出了问题影响的服务太多,此时就希望能有一个比较规范的测试流程.在github上看到牛逼的javascript开 ...
- CRL快速开发框架系列教程十一(大数据分库分表解决方案)
本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...
- vs15 preview5 离线安装包
1.介绍 vs15是微软打造的新一代IDE,全新的安装方式.官网介绍如下(https://blogs.msdn.microsoft.com/visualstudio/2016/10/05/announ ...
- python10作业思路及源码:类Fabric主机管理程序开发(仅供参考)
类Fabric主机管理程序开发 一,作业要求 1, 运行程序列出主机组或者主机列表(已完成) 2,选择指定主机或主机组(已完成) 3,选择主机或主机组传送文件(上传/下载)(已完成) 4,充分使用多线 ...
- Atitit.软件研发团队建设原理与概论 理论
Atitit.软件研发团队建设原理与概论 理论 培训 团队文化建设(内刊,ppt,书籍,杂志等) 梯队建设 技术储备人才的问题 团队建设--小红花评比. 团队建设--文化墙.doc 户外拓展 1. 团 ...
- OpenGL ES: Array Texture初体验
[TOC] Array Texture这个东西的意思是,一个纹理对象,可以存储不止一张图片信息,就是说是是一个数组,每个元素都是一张图片.这样免了频繁地去切换当前需要bind的纹理,而且可以节省系统资 ...