开发者社区> 丁国华> 正文

摸不到的颜色是否叫彩虹,输不对的密码是否叫做验证码

简介:         摸不到的颜色是否叫彩虹,输不对的密码是否叫做验证码`(*∩_∩*)′,我想小伙伴都有这样的经历,登陆QQ的时候,总是输不对密码,这个时候,多次进行登录,就会出现请输入验证码的选项,双十一那天狂买的小伙伴是不是对输入验证码有着不一样...
+关注继续查看
        摸不到的颜色是否叫彩虹,输不对的密码是否叫做验证码`(*∩_∩*)′,我想小伙伴都有这样的经历,登陆QQ的时候,总是输不对密码,这个时候,多次进行登录,就会出现请输入验证码的选项,双十一那天狂买的小伙伴是不是对输入验证码有着不一样的感触呢,以前觉得验证码真是个麻烦鬼,每次登陆还得输入验证码,一个不小心,一个眼拙,哎呦,没有输入正确,又是一阵子大眼瞪小眼,这个时候,突然想起做软件的不都是本着为人民服务的那颗滚烫的心么?怎么总让用户输入验证码,这不是给用户带来麻烦么?我想应该没有哪个用户会愿意输入验证码,特别是对于视力不是太好的小伙伴,有时候很坑姐,明明记得是输对了,但是最后显示的是验证码输入错误,这是否跟咱们的软件为人民服务相违背呢呢?小编感触最深的就是春节回家买火车票的时候,小编买到火车票的之后,由于验证码输入错误或者提交失败一直到提交成功的时候,显示的却是票不足,购票不成功,这多伤小编的心啊。为此,小编百思不得其解。直到那天,我懂了你……

        我恍如隔世,忽然从梦中惊醒,是小编想的太少,小编总是为自己的方便着想,没有想到程序员的难处,当然程序员是想让大家方便,但是没有事事那么完美无瑕,所以为了大家方便的同时,程序员遇到更大的一个难题就是安全,而验证码是一种区分用户是计算机和人的全自动程序,可以防止,恶意破解密码、刷票、论坛灌水,有效防止某个黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登陆尝试,实际上是用验证码是现在很多网站通行的方式(比如招商银行的网上个人银行,百度社区),程序员利用比较简易的方式实现了这个功能。到现在也许有很多的用户反映到登陆输入验证码太麻烦了,所以看到有一些网站是第一次登陆不需要输入验证码,然后你输入用户名或者密码不对的时候,就是登陆不成功的时候,验证码才出来,毕竟那是电脑,没有人脑那么灵活,所以程序员就让给电脑一个灵感,但登陆不成功的时候,为了安全,就给出验证码,这就很好的有效防止某个黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登陆尝试了,这就实现了安全。我们看一下腾讯QQ是怎么做的:

              

             如果多次登陆不成功,就会出现如下窗口提示:

             

        我们的验证码出来了,这就证明了我们的验证码确实能有效防止某个黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登陆尝试进行破解。所以当我们要输入验证码的时候,我们要想到这些,就不必心烦了,程序员想的不是不周到,是想让大家的数据更加安全,也为我们的秘密泄露加上了更好的防护。转念又想,至于春运买火车票的,小编总是抱怨说输入验证码导致自己没买到票,换句话说,要是不输入验证码,那更买不到了,至于人家的铁道部网站做的怎么样,我们先不讨论。相信很多人跟小编一样,有过这样的经历,其实特别美好,如果没有这样的疑惑,我们就没有进步的动力,就难以跟上时代的步伐。今天,小编就带领大家来揭开验证码的神奇面纱,看看她的背后是如何工作?首先我们做一个登陆页面,来看看验证码的背后是怎么工作的:

          

<span style="font-size:18px;"><%@ Page Language="C#" AutoEventWireup="true" CodeFile="login.aspx.cs" Inherits="admin_login" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>后台登陆-牛腩新闻发布系统</title>
    <link href="../css/login.css" rel="stylesheet" type="text/css" />
    <script language="javascript" type="text/javascript">
        function changeCode() {
            var imgNode = document.getElementById("vimg");
            imgNode.src = "../handler/WaterMark.ashx?t=" + (new Date()).valueOf();  // 这里加个时间的参数是为了防止浏览器缓存的问题   
        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div id="loginfrm" class="round1">
      <h3>后台登陆-牛腩新闻发布系统</h3>
      <div id="login">
        <img src="../images/niunanlogo.jpg" alt="LOGO" class="login_logo" />
        <p>用户名:<asp:TextBox ID="txtName" runat="server" CssClass="textbox"></asp:TextBox>
            <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="txtName" ErrorMessage="姓名不能为空">*123</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="" onclick="changeCode()"/>
                    <asp:TextBox ID="txtCode" runat="server" CssClass="textcode"></asp:TextBox>
            <asp:RequiredFieldValidator ID="RequiredFieldValidator3" runat="server" ErrorMessage="请输入验证码!" Text="*" ControlToValidate="txtCode"></asp:RequiredFieldValidator>
        </p>
          <asp:ValidationSummary ID="ValidationSummary1" runat="server" />
          <p>
              <asp:Button ID="btnLogin" runat="server" Text="登陆" onclick="btnLogin_Click" /></p>  
      </div>
      <div id="footer">版权所有 &copy; <a href="http://niunan.javaeye.com" target="_blank">牛腩</a>&<a href="http://www.tg029.com"
            target="_blank">众志网 </a></div>
    </div>
    </form>
</body>
</html></span>
             Login.aspx.cs的代码:

             

<span style="font-size:18px;">using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using BLL;
using System.Web.Security;

public partial class admin_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 rightCode = Session["Code"].ToString();
        if (code != rightCode)
        {
            Page.ClientScript.RegisterStartupScript(Page.GetType(), "message", "<script language='javascript' defer>alert('验证码输入错误!');</script>");
            return;
        }

        string name = txtName.Text.Trim();
        string pwd = txtPassword.Text.Trim();

        // 把密码转为MD5码的形式
        pwd = FormsAuthentication.HashPasswordForStoringInConfigFile(pwd, "MD5");

        bool b = LoginManager.Login(name, pwd);
        if (b)
        {
            //  登陆成功
            Session["admin"] = name;
            Response.Redirect("categorymanager.aspx");
        }
        else
        {
            Page.ClientScript.RegisterStartupScript(Page.GetType(), "message", "<script language='javascript' defer>alert('登陆失败,用户名或者密码错误!');</script>");
        }

    }
}
</span>
              css排版中的代码

             

<span style="font-size:18px;">/* 
*登陆验证码测试 
*/  
  
     *  
{  
    margin :0;  
    padding :0;  
    }  
body   
{  
    font-size :14px;  
}  
  
  
#loginfrm #login p  
{  
    padding-bottom :10px;  
    }  
.textbox  
{  
    width :150px;  
    }  
.txtCode  
{  
    width :73px;  
    }  </span>
        业务逻辑层:

        

<span style="font-size:18px;">/*
 *创建人:丁国华
 *创建时间:2014年11月19日 14:36:59
 *说明:登陆的业务逻辑类
 *版权所有:丁国华&www.tg029.com(众志网)
 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace BLL
{
    public class LoginManager
    {
        #region 用户登陆是否成功
        /// <summary>
        /// 用户登陆是否成功
        /// </summary>
        /// <param name="name">用户名</param>
        /// <param name="pwd">密码</param>
        /// <returns></returns>
        public static bool Login(string name, string pwd)
        {
            bool flag = false;
           if ("niunan" == name && "E10ADC3949BA59ABBE56E057F20F883E" == pwd)
            {
                flag = true;
            }
            return flag;

        }
        #endregion
    }
    
}
</span>
              最后我们来看看验证码这块的内容:

              

<span style="font-size:18px;"><%@ WebHandler Language="C#" Class="WaterMark" %>
/*
 * 创建人:丁国华
 * 创建时间:2014年11月22日 21:54:52
 * 版权所有:丁国华&众志网(www.tg029.com)
 */
using System;
using System.Web;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Web.SessionState;  

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

    public void ProcessRequest(HttpContext context)
    {
        string checkCode = GenCode(5);  // 产生5位随机字符
        context.Session["Code"] = checkCode; //将字符串保存到Session中,以便需要时进行验证
        System.Drawing.Bitmap image = new System.Drawing.Bitmap(70, 22);
        Graphics g = Graphics.FromImage(image);
        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));
            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);

            //画图片的前景噪音点
            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);
            context.Response.ClearContent();
            context.Response.ContentType = "image/Gif";
            context.Response.BinaryWrite(ms.ToArray());
        }
        finally
        {
            g.Dispose();
            image.Dispose();
        }
    }

    /// <summary>
    /// 产生随机字符串
    /// </summary>
    /// <param name="num">随机出几个字符</param>
    /// <returns>随机出的字符串</returns>
    private string GenCode(int num)
    {
        string str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        char[] chastr = str.ToCharArray();
        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);
        }
        return code;

    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }

}</span>
          最后,我们来看一下我们的界面效果:

          

         这个登录验证码的窗体已经完成了,我们看的出来验证码其实就是通过一张图片,来区分用户和计算机,就能达到很好的防止:恶意破解密码、刷票、论坛灌水,有效防止某个黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登陆尝试;所以为了咱们的网络安全,这个验证码确实发挥了很大的作用。牛腩新闻发布系统,未完,待续......

              

            

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
18999 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
25240 0
阿里云服务器ECS登录用户名是什么?系统不同默认账号也不同
阿里云服务器Windows系统默认用户名administrator,Linux镜像服务器用户名root
13953 0
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
20697 0
使用SSH远程登录阿里云ECS服务器
远程连接服务器以及配置环境
13983 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,大概有三种登录方式:
10019 0
腾讯云服务器 设置ngxin + fastdfs +tomcat 开机自启动
在tomcat中新建一个可以启动的 .sh 脚本文件 /usr/local/tomcat7/bin/ export JAVA_HOME=/usr/local/java/jdk7 export PATH=$JAVA_HOME/bin/:$PATH export CLASSPATH=.
14118 0
使用OpenApi弹性释放和设置云服务器ECS释放
云服务器ECS的一个重要特性就是按需创建资源。您可以在业务高峰期按需弹性的自定义规则进行资源创建,在完成业务计算的时候释放资源。本篇将提供几个Tips帮助您更加容易和自动化的完成云服务器的释放和弹性设置。
18716 0
+关注
丁国华
你只管努力,剩下的交给时光!
214
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
JS零基础入门教程(上册)
立即下载
性能优化方法论
立即下载
手把手学习日志服务SLS,云启实验室实战指南
立即下载