随手记_C#验证码

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 前言 最近在网上偶然看见一个验证码,觉得很有意思,于是搜了下,是使用第三方实现的,先看效果:     总体来说效果还是可以的,官方提供的SDK也比较详细,可配置性很高。在这里在简单啰嗦几句使用方式: 使用步骤 ①进入官网下载sdk接口→ http://www.geetest.com/install/ ,因为小弟是做C#的,所以此处选择C#,具体选择看各位大佬所用语言决定~ ②第二步,获取代码,访问红框所示地址,下载demo。

前言

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

 

 

总体来说效果还是可以的,官方提供的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 = 0;
            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 == 1) result = geetest.enhencedValidateRequest(challenge, validate, seccode, userID);
            else result = geetest.failbackValidateRequest(challenge, validate, seccode);
            if (result == 1) 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>
                    <!-- 请输入验证码-->
                    &nbsp;&nbsp;
                         <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(1, 10), "image/jpeg");
            }
        }

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

  public class VerificationCodeHelper
    {
        private static Color BackColor = Color.White;
        private static int Width = 62;
        private static int Height = 21;
        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, 0, 0, Width - 1, Height - 1);//绘画边框
                    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(), 3, 1);
        }

        /// <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 = 0; n < 30; 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(0, FontItems.Length);
            FontStyle fontStyle = GetFontStyle(_random.Next(0, 2));
            return new Font(FontItems[fontIndex], 12, 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(0, 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 0:
                    return FontStyle.Bold;
                case 1:
                    return FontStyle.Italic;
                default:
                    return FontStyle.Regular;
            }
        }

        /// <summary>
        /// 取得一个 4 位的随机码
        /// </summary>
        /// <returns></returns>
        public string GetRandomCode()
        {
            return Guid.NewGuid().ToString().Substring(0, 5);
        }
    }
View Code

注意,初次加载页面的时候,将拿到的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 = "0", MSG = "请填写验证码" });
                else
                {
                    if (Session["code"] == null)
                        return Json(new { Result = "0", MSG = "验证码已过期,请点击刷新验证码" });
                    string str = Session["code"].ToString();
                    str = str.ToLower();
                    vccode = vccode.ToLower();
                    if (str != vccode)
                        return Json(new { Result = "0", MSG = "验证码填写错误!" });
                    else
                    {
                        Session["code"] = null;
                    }
                    if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(pwd))
                    {
                        return Json(new { Result = "0", MSG = "用户或密码没有填写" });
                    }
                    //查询此用户
                    #region 查询此用户
                    List<Models.MySqlUser> adminml = new List<Models.MySqlUser>();
                    Models.MySqlUser admin = new Models.MySqlUser();
                    adminml = IBCodeBll.GetModelList(userName.Trim());

                    if (adminml.Count > 0)
                    {
                        if (!adminml[0].password.ToLower().Equals(Maticsoft.Common.DEncrypt.DESEncrypt.Encrypt2(pwd.Trim()).ToLower()))
                        {
                            return Json(new { Result = "0", MSG = "密码错误!" });
                        }
                    }
                    else
                    {
                        return Json(new { Result = "0", MSG = "用户不在在!" });
                    }
                    #endregion
                    Session["UserName"] = userName.Trim().ToString();
                    return Json(new { Result = "1", MSG = "登录成功!" });
                }
            }
            catch (Exception ex)
            {

                return Json(new { Result = "0", MSG = ex.Message });
            }
        }

 

      End!

  • 感谢你的阅读。如果你觉得这篇文章对你有帮助或者有启发,就请推荐一下吧~你的精神支持是博主强大的写作动力。欢迎转载!
  • 博主的文章没有高度、深度和广度,只是凑字数。由于博主的水平不高(其实是个菜B),不足和错误之处在所难免,希望大家能够批评指出。
  • 欢迎加入.NET 从入门到精通技术讨论群→523490820 期待你的加入
  • 不舍得打乱,就永远学不会复原。被人嘲笑的梦想,才更有实现的价值。
  • 我的博客:http://www.cnblogs.com/zhangxiaoyong/
相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
C# 开发工具
C#滑动拼图验证码实现笔记
C# 是一个现代的、通用的、面向对象的编程语言,它是由微软(Microsoft)开发的,由 Ecma 和 ISO 核准认可的。突发奇想,动手开发一个C#滑动拼图验证码,下面是我开发过程的记录。
C#滑动拼图验证码实现笔记
|
前端开发 机器人 C#
C#登录验证码
相信大家都明白,大多数的网站为了不被恶意访问,往往需要设置验证码登录,避免机器人访问,而造成我服务器瘫痪,崩溃,下面就来看看实现的具体过程吧!
C#登录验证码
|
前端开发 C# 数据安全/隐私保护
C#验证码
验证码通常是为了区分用户是人还是计算机,也可以防止破解密码、刷票等恶意行为,而客户端上多数会用在关键操作上,比如购买、登录、注册等场景。现在验证码的种类样式也特别多,今天教大家如何用C#做出滑动拼图验证码吧~
C#验证码
|
前端开发 C# 开发工具
想用C# .Net生成行为验证码,还得看这篇文章
为了增强网站的安全性,我们在网站的登录模块或信息输入模块加入了验证码功能,那么在C# .Net中如何实现验证码呢?本文借助KgCaptcha实现了这个功能。
想用C# .Net生成行为验证码,还得看这篇文章
|
C# 数据安全/隐私保护
C#实现手机发送验证码
C#实现手机发送验证码
502 0
|
C# 图形学 索引
|
关系型数据库 C# 数据安全/隐私保护