牛腩新闻发布系统-验证码搞通了吗?详细注释-秒懂!

    牛腩新闻发布系统添加新闻和登录界面用到了验证码,生活中经常遇到形形色色的验证码,数字和字母的,12306图片形式的,百度贴吧文字形式的等等。当时见得时候感觉很神奇,现在刚好学到了,感觉很有意思,接触了BS之后,越来越多的网页神秘的内容,会慢慢的被了解,这种渴望的感觉特别棒。见到了自己喜欢的那就应该认真的分析,理解验证码的产生,这里说的是数字和字母类型的,从简单的入手。

什么是验证码,它是干什么的?

    验证码:是一种区分用户是计算机还是人的公共全自动程序。可以防止:恶意破解密码、刷票、论坛灌水,有效防止某个黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登陆尝试。

    学习验证码的生成知识,内容涉及到了HTML,JavaScript,CSS,还有C#语言代码。经过认真学习,整体上理清了各部分之间的实现关系。

HTML代码:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="login.aspx.cs" Inherits="Web.admin.login" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>后台登陆-牛腩新闻发布系统</title>

    <link href="../CSS/login.css" rel="stylesheet" />   <!--引用-->
    <script lang="javascript" type="text/javascript">
        function changeCode() {
            var imgNode = document.getElementById("vimg");     // 得到的是一个对象。根据网页中 id=vimg 的元素; 
            imgNode.src = "hander/WaterMark.aspx?t=" + (new date()).valueOf();//这里加个时间的参数防止浏览器。刷新验证码字符;
        }

    </script>
</head>
<body>
    <form id="form1" runat="server">
        <!--CSS的可重用性-->
        <div id="loginfrm" class="round1">

            <h3>后台登陆-牛腩新闻发布系统</h3>

            <div id="login">
                <img src="../images/niunanlogo.jpg" alt="LOGO" class="login_logo" />
                <!--P是块级元素换行-->
                <p>
                    用户名:<asp:TextBox ID="txtName" runat="server" CssClass="textbox"></asp:TextBox>
                    <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ErrorMessage="请输入用户名!" Text="*" ControlToValidate="txtName"></asp:RequiredFieldValidator>
                </p>
                <p>
                    密__码:<asp:TextBox ID="txtPassword" runat="server" TextMode="Password" CssClass="textbox"></asp:TextBox>
                    <asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server" ErrorMessage="请输入密码!" Text="*" ControlToValidate="txtPassword"></asp:RequiredFieldValidator>
                </p>
                <p>
                    验证码:<img src="../handler/WaterMark.ashx" id="vimg" alt="" οnclick="changCode()" />
                    <asp:TextBox ID="txtCode" runat="server" CssClass="textcode"></asp:TextBox>
                    <asp:RequiredFieldValidator ID="RequiredFieldValidator3" runat="server" ErrorMessage="请输入验证码!" Text="*" ControlToValidate="txtCode"></asp:RequiredFieldValidator>
                </p>
                <p>
                    <asp:Button ID="btnLogin" runat="server" Text="登陆" OnClick="btnLogin_Click" />
                    <asp:ValidationSummary ID="ValidationSummary1" runat="server" ShowMessageBox="true" ShowSummary="false" />
                </p>
            </div>

            <div id="footer">
                版权所有 &copy <a href="http://www.baidu.com" target="_blank">牛腩</a> & <a href="http://www.baidu.com" target="_blank">众志网</a>
            </div>
        </div>
    </form>
</body>
</html>

    HTML代码中, 验证码:<img src="../handler/WaterMark.ashx" id="vimg" alt="" οnclick="changCode()" /> 这里<img> 元素向网页中嵌入一幅图像。文件后缀为.ashx的文件,是一般处理程序生成的图片引用过来。给他一个表示的id。当点击这个图片的时候。οnclick="changCode()"当点击按钮时执行<head>中的一段 JavaScript。

这里用到了两个验证控件;

    RequiredFieldValidator:用于使输入控件成为一个必选字段。通过该控件,如果输入值的初始值未改变,那么验证将失败。默认地,初始值是空字符串 ("")。
Runat:该控件为服务器控件;ErrorMessage:当验证失败时,在ValidationSummary控件中显示的文本。Text=当验证失败时显示的信息;ControlToValidate:要验证的控件的id;该控件通过ControlToValidate:属性的值与要验证控件的id相结合。
    ValidationSummary:用于在网页、消息框或在这两者中内联显示所有验证错误的摘要。在该控件中显示的错误消息是由每个验证控件的 ErrorMessage 属性规定的。
ShowMessageBox:布尔值,指示是否在消息框中显示验证摘要。弹出框中出现;
ShowSummary:布尔值,规定是否显示验证摘要;

    这两个验证控件经常结合使用;

C#代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using BLL;
using Model;
using System.Web.Security;

namespace Web.admin
{
    public partial class login : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }
        //登录按钮
        protected void btnLogin_Click(object sender, EventArgs e)
        {
            //判断验证码是否输入正确;
            string code = txtCode.Text.Trim().ToUpper();
            string rigthCode = Session["Code"].ToString();  //从一般处理程序中产生,这里获得。

            if (code != rigthCode)<span style="white-space:pre">	</span>//判断验证码字符和用户输入的验证码是否一致;如果不相等
            {
                //Response.Write("<script>alert('验证码输入错误!')</script>");
                Page.ClientScript.RegisterStartupScript(Page.GetType(), "message", "<script lang='javascript' defer>alter('验证码输入错误!');</script>");
                return;
            }
<span style="white-space:pre">	</span>    //如果相等;
            string name = txtName.Text .ToString();      //把页面上文本框中的值赋给变量;
            string pwd = txtPassword.Text.ToString();

            //把密码转为MD5码的形式;密码暗码;
            pwd = FormsAuthentication.HashPasswordForStoringInConfigFile(pwd, "MD5");
           
            bool b = LoginManager.Login(name, pwd);
            if (b)
            {
                //跳转
                Session["admin"] = name;     //把用户名给Session["admin"]程序以后会用到;

                Response.Redirect("categorymanager.aspx");//跳转到该页面;
            }
            else
            {//给出弹框提示;
                Page.ClientScript.RegisterStartupScript(Page.GetType(), "message", "<script language='javascript' defer>alert('登陆失败,用户名或者密码错误!');</script>");
            }

        }
    }
}

C#代码的主要内容是判断验证码输入是否正确,验证码输入正确之后,判断用户名和密码是否正确,如果正确跳转到Categorymanager页面;


一般处理程序;

<pre name="code" class="csharp"><%@ WebHandler Language="C#" CodeBehind="WaterMark.ashx.cs" Class="Web.handler.WaterMark" %>

using System;
using System.Web;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Web.SessionState;

namespace Web.handler
{
    public class WaterMark : IHttpHandler, IRequiresSessionState  // 要使用session必须实现该接口,记得要导入System.Web.SessionState命名空间
    {

        public void ProcessRequest(HttpContext context)
        {
            string checkCode = GenCode(5);  // 产生5位随机字符。根据下面的GenCode变量;
            context.Session["Code"] = checkCode; //将字符串保存到Session中,以便登录时进行验证
            System.Drawing.Bitmap image = new System.Drawing.Bitmap(70, 22);    //是用于处理由像素数据定义的图像的对象.<70*22>
            Graphics g = Graphics.FromImage(image);//Grapgics对象类似画布或者一张纸,供其他对象在上面作图。把图片画到该对象上;

            try
            {
                //生成随机生成器
                Random random = new Random();

                //清空图片背景色
                g.Clear(Color.White);

                // 画图片的背景噪音线
                int i;
                for (i = 0; i < 25; i++)
                {
                    int x1 = random.Next(image.Width);  //产生非负随机数;
                    int x2 = random.Next(image.Width);
                    int y1 = random.Next(image.Height);
                    int y2 = random.Next(image.Height);
                    g.DrawLine(new Pen(Color.Silver), x1, y1, x2, y2);  //实例化一个颜色的笔,然后根据这四个点 打印出页面的边框。
                }

                Font font = new System.Drawing.Font("Arial", 12, (System.Drawing.FontStyle.Bold)); //文字格式                                                             //LinearGradientBrush 构造函数 (Rectangle, Color, Color, Single, Boolean)根据矩形、起始颜色和结束颜色以及方向角度,创建 LinearGradientBrush 类的新实例。
               System.Drawing.Drawing2D.LinearGradientBrush brush = new System.Drawing.Drawing2D.LinearGradientBrush(new Rectangle(0, 0, image.Width, image.Height), Color.Blue, Color.DarkRed, 1.2F, true);                                                                                                                       g.DrawString(checkCode, font, brush, 2, 2);//使用此图形上下文的当前字体和颜色绘制由指定 string 给定的文本。checkCode为产生的5个随机数,设置他们的格式;
               //画图片的前景噪音点  //DrawRectangle矩形的长度和宽度指的是象素之间的间隔数,因此如果要绘制DrawRectangle ( Pens.Black, 0,0, 5,4);最终会得到长为6个象素宽为5个象素的矩形框。 
                g.DrawRectangle(new Pen(Color.Silver), 0, 0, image.Width - 1, image.Height - 1);
                System.IO.MemoryStream ms = new System.IO.MemoryStream();//创建其支持存储区为内存的流。  
                image.Save(ms, System.Drawing.Imaging.ImageFormat.Gif); //将此 Image 以指定格式保存到指定文件。 S保存图片格式为 GIF. 
                context.Response.ClearContent();//ClearContent方法不仅删除Response显示输出信息而且还删除Response头信息
                context.Response.ContentType = "image/Gif";//显示为GIF的图片格式; 
                context.Response.BinaryWrite(ms.ToArray());//输出gif 图片  
            }
            finally
            {
                g.Dispose();
                image.Dispose();
            }
        }

        /// <summary>
        /// 产生随机字符串
        /// </summary>
        /// <param name="num">随机出几个字符</param>
        /// <returns>随机出的字符串</returns>
        private string GenCode(int num)
        {                                                                  //根据前面参数,产生5个随机数;   
            string str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
            char[] chastr = str.ToCharArray();
            // string[] source ={ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "#", "$", "%", "&", "@" };
            string code = "";
            Random rd = new Random();
            int i;
            for (i = 0; i < num; i++)
            {
                //code += source[rd.Next(0, source.Length)];
                code += str.Substring(rd.Next(0, str.Length), 1);//Substring:字符串的字字符串、该子字符串从指定的 beginIndex 处开始,直到索引 endIndex - 1 处的字符  
            }
            return code;

        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }

    }
}
 
一般处理程序生成动态图片和动态文本,这里用来生成验证码图片。 


3个部分代码的各自分工:

    一般处理程序:用来生成5个随机数,给随机数设置好大小,前景噪音点,背景噪音点。最终形成一张GIF格式的图片。

    HTML代码:对图片前台显示格式的设置,以及点击图片可以重新更换。因为是登录界面,界面上文本框和验证码中信息的验证。

    C#代码:与数据库建立连接,对产生的验证码和用户输入的验证码进行对比判断,验证码正确的基础上进行登录信息,用户名和密码的验证。最终判断是否可以登录。



总结:

    通过学习牛腩,分析验证码的整个流程,知道了验证码是怎么产生的,对这部分内容比较感兴趣,生活中处处需要验证码。随着BS的学习,会掌握越来越多经常见到以前觉得神奇,不属于自己的东西。解开神秘面纱,神奇的旅程。

  • 2
    点赞
  • 1
    收藏
  • 打赏
    打赏
  • 40
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:编程工作室 设计师:CSDN官方博客 返回首页
评论 40

打赏作者

随心更博

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值