• 随手记_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 = 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;  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!

  • 相关阅读:
    用java抓取网页信息!
    WPF之Binding对数据的转换(第五天)
    WPF读书笔记 x名称空间详解(第二天)
    WPF的UI布局(Layout)WPF读书笔记(第三天)
    WPF 数据绑定Bingding基础(第四天)
    WPF读书笔记(第一天)
    HelloWin程序(窗口与消息)
    django创建数据库表方法
    OpenSSH利用处理畸形长度密码造成的时间差,枚举系统用户(CVE20166210)
    ldap匿名访问测试脚本
  • 原文地址:https://www.cnblogs.com/zhangxiaoyong/p/6210953.html
Copyright © 2020-2023  润新知