预知内容:
1、图片验证码是防止暴力破解机制。计算机目前还是很难识别图形的。但是人眼却可以轻松的认出来!
2、rand.Next(1000,10000)左闭右开的区间
1、、在模板页中添加图片展示:sessiontest1.html
<!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 action="sessiontest1.ashx" method="post"> <table> <tr><td>用户名:</td><td><input type="text" name="username" /></td></tr> <tr><td>密 码:</td><td><input type="password" name="pwd" /></td></tr> <tr><td><img src="sessionAnLi2.ashx" /></td></tr> <tr><td><input type="submit" name="btn1" value="登陆" /></td><td>{msg}</td></tr> </table> </form> </body> </html>
2、、写产生验证图图片一般处理程序;sessionAnLi2.ashx
using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.Linq; using System.Web; namespace Web1.Seession { /// <summary> /// sessionAnLi2 的摘要说明 /// </summary> public class sessionAnLi2 : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "image/jpeg";//1,修改报文输出的类型 //2、实例化一个随机对象 Random rand = new Random(); //3、确定范围 int num = rand.Next(1000,10000);//取值做闭右开的 string shuzi = num.ToString(); //4、调用GDI画图, using (Bitmap bmp = new Bitmap(70, 25)) { using(Graphics g=Graphics.FromImage(bmp)) using (Font font = new Font(FontFamily.GenericSerif, 15)) { g.DrawString(shuzi, font, Brushes.Red, new PointF(0, 0)); } bmp.Save(context.Response.OutputStream, ImageFormat.Jpeg); } } public bool IsReusable { get { return false; } } } }
3、、问题是怎么点击图片让其重新生成验证码:使用js对模板页的控制(发现模板页的好处!)
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title></title> <script type="text/javascript"> function refreshYZM(){ var imgyzm = document.getElementById("imgyzm"); imgyzm.src = "sessionAnLi2.ashx?t=" + new Date(); //加上当前时间,让这次的src和上次不一样,这样就会重新加载验证码了 } </script> </head> <body> <form action="sessiontest1.ashx" method="post"> <table> <tr><td>用户名:</td><td><input type="text" name="username" /></td></tr> <tr><td>密 码:</td><td><input type="password" name="pwd" /></td></tr> <tr><td><img src="sessionAnLi2.ashx" id="imgyzm" onclick="refreshYZM()" /></td><td></td></tr> <tr><td><input type="submit" name="btn1" value="登陆" /></td><td>{msg}</td></tr> </table> </form> </body> </html>
4、、在登陆页面声明一个常量存
/// </summary> public class sessiontest1 : IHttpHandler, IRequiresSessionState//10、 实现接口,shift+alt+f10导入命名 { public const string LOGINNAME = "loginname"; public const string LOGINBEFOREURL = "loginTryUrl";//尝试登陆时候的页面地址 public const string YZM = "yzm";
5、、在模板页修改
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title></title> <script type="text/javascript"> function refreshYZM(){ var imgyzm = document.getElementById("imgyzm"); imgyzm.src = "sessionAnLi2.ashx?t=" + new Date(); //加上当前时间,让这次的src和上次不一样,这样就会重新加载验证码了 } </script> </head> <body> <form action="sessiontest1.ashx" method="post"> <table> <tr><td>用户名:</td><td><input type="text" name="username" /></td></tr> <tr><td>密 码:</td><td><input type="password" name="pwd" /></td></tr> <tr><td><img src="sessionAnLi2.ashx" id="imgyzm" onclick="refreshYZM()" /></td><td><input type="text" name="yzm00"</td></tr> <tr><td><input type="submit" name="btn1" value="登陆" /></td><td>{msg}</td></tr> </table> </form> </body> </html>
6、、在登陆处理程序中修改,,登陆之前首先做验证码的验证,防止暴力破解
using System; using System.Collections.Generic; using System.Data.SqlClient; using System.Linq; using System.Web; using System.Web.SessionState; using Web1.Day3; namespace Web1.Seession { /// <summary> /// sessiontest1 的摘要说明 /// </summary> public class sessiontest1 : IHttpHandler, IRequiresSessionState//10、 实现接口,shift+alt+f10导入命名 { public const string LOGINNAME = "loginname"; public const string LOGINBEFOREURL = "loginTryUrl";//尝试登陆时候的页面地址 public const string YZM = "yzm"; //为了以后方便加处理代码,以后用户都访问.ashx,而不是直接访问html public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/html"; //1、从请求报文中读取,btn1 string btnLogin = context.Request["btn1"]; //2、读取html页面 string html = CommonHelper.ReadHtml("~/Seession/sessiontest1.html"); //3、判断 if (string.IsNullOrEmpty(btnLogin)) { //4、初始化登陆页面,{msg} html = html.Replace("{msg}", ""); context.Response.Write(html); } else { //在登陆之前首先验证验证码是否争取 string yzm = context.Request["yzm00"]; string yzmInServe = (string)context.Session[YZM]; if (yzmInServe != yzm) { html = html.Replace("{msg}", "验证码错误!"); context.Response.Write(html); return; } //5、否则从请求报文中读取用户名和密码的 string username = context.Request["username"]; string pwd = context.Request["pwd"]; //6、到数据库中查询 int count = (int)SqlHelper.ExecuteScalar( "select count(*) from T_Users where Name=@Name and Password=@Password", new SqlParameter("@Name", username), new SqlParameter("@Password", pwd)); //7、根据返回的整数判断 if (count <= 0) { //8、替换{msg} html = html.Replace("{msg}", "登陆失败!"); context.Response.Write(html); } else { //9、登陆成功,页面跳转!并//将用户名存入到session中,这样其它页面就可以读取这个session context.Session[sessiontest1.LOGINNAME] = username; //12、读取存入登陆前页面的url地址,从Session中(读) string navUrl = (string)context.Session[sessiontest1.LOGINBEFOREURL]; //13、如果你登陆前的地址有,就重定向登陆前的页面 if (navUrl != null) { context.Response.Redirect(navUrl); } else { context.Response.Redirect("ChangePassword.ashx");//默认进入密码修改页 } } } } public bool IsReusable { get { return false; } } } }
7、、加断点调试验证