由于现在的注册机、发帖机等垃圾软件实在太多,为了有效的拦截这些信息,许多站点都需要用到验证码,下面就用HttpHandler实现的验证码机制
- /* ***********************************************
- * Author: 1987raymond
- * Team: Juice Sharing
- * Created Time: 2009-3-10 19:22:46
- * CopyRight: Juice Sharing 团队版权所有 保留一切权利
- * NameSpace: Juice.Common.HttpHandlers
- * Class/Interface: ValidateCodeRender
- * ***********************************************/
- using System;
- using System.Text;
- using System.Web;
- using System.Drawing;
- using System.Drawing.Imaging;
- using System.Web.SessionState;
- namespace Juice.Common.HttpHandlers
- {
- /// <summary>
- /// 验证码生成器
- /// </summary>
- public sealed class ValidateCodeRender : IHttpHandler, IRequiresSessionState
- {
- /// <summary>
- /// 构造函数
- /// </summary>
- public ValidateCodeRender()
- { }
- #region 私有字段
- /// <summary>
- /// 验证码的长度
- /// </summary>
- private int m_CodeLength = 5;
- /// <summary>
- /// 保存到会话状态中的值
- /// </summary>
- private string m_SessionName = "validateCode";
- /// <summary>
- /// 图像的宽
- /// </summary>
- private int m_ImageWidth = 160;
- /// <summary>
- /// 图像的长
- /// </summary>
- private int m_ImageHeight = 60;
- /// <summary>
- /// 图像背景色
- /// </summary>
- private Color m_BackgroundColor = Color.FromArgb(212, 236, 189);
- /// <summary>
- /// 图像上验证码的颜色
- /// </summary>
- private Color m_CodeColor = Color.FromArgb(132, 199, 1);
- /// <summary>
- /// 干扰图形的颜色
- /// </summary>
- private Color m_ObstructionColor = Color.Gray;
- /// <summary>
- /// 用来生成随机验证码的字符串
- /// </summary>
- private const string m_CodeString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890我和你的大小";
- #endregion
- #region IHttpHandler 成员
- /// <summary>
- /// 是否可以重用
- /// </summary>
- public bool IsReusable
- {
- get { return true; }
- }
- /// <summary>
- /// 处理请求
- /// </summary>
- /// <param name="context"></param>
- public void ProcessRequest(HttpContext context)
- {
- ///设置输出的格式
- context.Response.ContentType = "image/gif";
- Random random = new Random();
- ///用来保存随机取得的字符串
- StringBuilder s = new StringBuilder();
- ///创建绘图的图像
- using (Bitmap bitmap = new Bitmap(this.m_ImageWidth, this.m_ImageHeight))
- {
- ///创建绘图图面,用此对象将各种符号等绘制到制定的图像上
- using (Graphics graphics = Graphics.FromImage(bitmap))
- {
- ///生成背景颜色
- graphics.FillRectangle(new SolidBrush(this.m_BackgroundColor), 0, 0, this.m_ImageWidth, this.m_ImageHeight);
- #region 生成验证码
- ///验证码的字体
- using (Font font = new Font(FontFamily.GenericSerif, 32, FontStyle.Bold | FontStyle.Italic, GraphicsUnit.Pixel))
- {
- for (int i = 0; i < this.m_CodeLength; i++)
- {
- s.Append(ValidateCodeRender.m_CodeString.Substring(random.Next(0, m_CodeString.Length - 1), 1));
- ///将字符绘制到图像上
- graphics.DrawString(s[s.Length - 1].ToString(), font, new SolidBrush(this.m_CodeColor), i * 32, random.Next(0, 24));
- }
- }
- #endregion
- #region 绘制干扰图形和噪点
- //干扰图形绘制画笔
- using (Pen pen = new Pen(new SolidBrush(this.m_ObstructionColor), 1))
- {
- for (int i = 0; i < 10; i++)
- {
- graphics.DrawLine(pen, new Point(random.Next(0, this.m_ImageWidth - 1), random.Next(0, this.m_ImageHeight - 1)), new Point(random.Next(0, this.m_ImageWidth - 1), random.Next(0, this.m_ImageHeight - 1)));
- }
- }
- for (int i = 0; i < 100; i++)
- {
- bitmap.SetPixel(random.Next(this.m_ImageWidth), random.Next(this.m_ImageHeight), Color.FromArgb(random.Next()));
- }
- #endregion
- ///保存图像到输出流
- bitmap.Save(context.Response.OutputStream, ImageFormat.Gif);
- }
- }
- ///将验证码的值保存到用户会话状态中,并且不区分大小写
- context.Session[this.m_SessionName] = s.ToString().ToLower();
- context.Response.End();
- }
- #endregion
- }
- }
上面这个类就是绘制验证码图像并且输出到页面的类,它实现了IHttpHandler接口
下面再到web.config的 <httpHandlers>节点中添加此项:
- <add verb="GET" path="ValidateCode.aspx" validate="false" type="Juice.Common.HttpHandlers.ValidateCodeRender,Juice.Common" />
Juice.Common.HttpHandlers.ValidateCodeRender,Juice.Common 根据你自己的情形而定
下面则是在具体的页面中调用:
测试验证码:
- <img src="/ValidateCode.aspx" alt="验证码" id="validateCode" /><a
- href="javascript:refreshCode();">刷新验证码</a>
- <script language="javascript" type="text/javascript">
- function refreshCode()
- {
- var e=gid("validateCode");
- e.src="/ValidateCode.aspx"+"?t="+new Date().toTimeString();
- }
- </script>
效果如下图所示:
大家注意下这个地方:
- ///将验证码的值保存到用户会话状态中,并且不区分大小写
- context.Session[this.m_SessionName] = s.ToString().ToLower();
我是把验证码保存在Session中的,所以如果你需要检查某个用户输入是否正确就只需看其值和Session中的值是不是一样的
同时有一点注意下就是我看到一些网上教程所把验证码的值保存在Cookie中,我想这样做是错误的,而且丧失了验证码的功能,因为Cookie是客户端也可以访问的
大家还可以扩展验证码 的内容,比如改成算术等等的形式