1 Cookie的设置和获取:html
默认浏览器关闭,cookie就消失,设置有效期,就到期后才消失
cookie与浏览器相关,各类浏览器、同一浏览器窗口、小号模式,互不影响,各有一套cookie
cookie中不能存太多数据、不能存铭感的不能修改password的数据
cookie有可能提早消失,浏览器能够进行瘦身,或用户手动清楚cookieweb
public class cookie1 : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; //设置cookie HttpCookie cookie = new HttpCookie("test"); //cookie.Value = "rupeng.com"; cookie.Value = context.Request.UserAgent; //设置有效期,若是没有,则浏览器关闭就消失 cookie.Expires = DateTime.Now.AddSeconds(10); context.Response.SetCookie(cookie); } public bool IsReusable { get { return false; } } }
public class cookie2 : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; //获取cookie HttpCookie cookie = context.Request.Cookies["test"]; context.Response.Write(cookie==null?"没有这个cookie":cookie.Value); //修改cookie的值 //if(cookie!=null) //{ // cookie.Value = "Core就是必须学"; // context.Response.SetCookie(cookie); //} } public bool IsReusable { get { return false; } } }
2 Cookie实现记住登陆用户名:sql
当用户进入登陆界面时,若是cookie中记住了用户名 就自动填充用户名,不然不填数据库
当用户登陆时,若是登陆成功 就在cookie中记住用户名,不然跳转登陆界面浏览器
public class memoryUsername : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/html"; string login = context.Request["login"]; if(string.IsNullOrWhiteSpace(login)) //展现 { string html = CommonHelper.GetHtmlFromVirtualPath(context, "~/Day4/memoryUsername.html"); //展现时,先从cookie中查看是否有username,若是有就自动显示出用户名,若是没有就不显示 HttpCookie cookieUserName = context.Request.Cookies["LastUserName"]; if (cookieUserName != null) { string cookieValue = cookieUserName.Value; html = html.Replace("@username", cookieValue); context.Response.Write(html); } else { html = html.Replace("@username", ""); context.Response.Write(html); } } else //登陆 { //登陆时,若是登陆成功,无论有没有这个cookie,都从新设置cookie string username = context.Request["username"]; string password = context.Request["password"]; if (username == "admin" && password == "123") //登陆成功 { HttpCookie cookieUserName = new HttpCookie("LastUserName"); cookieUserName.Value = username; cookieUserName.Expires = DateTime.Now.AddDays(7); context.Response.SetCookie(cookieUserName); context.Response.Write("登陆成功"); } else { context.Response.Redirect("memoryUsername.ashx"); } } } public bool IsReusable { get { return false; } } }
<body> <form action="memoryUsername.ashx" method="post"> 用户名:<input type="text" name="username" value="@username" /><br /> 密码:<input type="password" name="password" /><br /> <input type="submit" name="login" value="登陆" /><br /> </form> </body>
3 Cookie中的Path路径:安全
cookie.Path 若是不设置,默认是\,表示当前域名下的全部页面均可以读取这个cookie,www.rupeng.com和www.rupeng.cn是2个不一样的域名,cookie不共用。服务器
cookie.Path="/Day4/cookiePath1.ashx" 设置path,表示只有这有这个‘/Day4/cookiePath1.ashx’页面,才能够读取这个cookie,不然不能读取不到这个cookie。cookie
cookie.Domain="rupeng.com" 设置cookie的域名,则不论是www.rupeng.com仍是bbs.rupeng.com均可以读取到这个cookie。cookie与域名有关。session
public class cookiePath1 : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; HttpCookie cookieRead = context.Request.Cookies["path"]; context.Response.Write(cookieRead == null ? "没有这个cookie" : cookieRead.Value+"||"+cookieRead.Path); //设置cookie HttpCookie cookie = new HttpCookie("path"); cookie.Value = "rupeng.com"; cookie.Expires = DateTime.Now.AddDays(1); cookie.Path = "/Day4/cookiePath1.ashx"; //只有cookiePath1.ashx才能访问这个cookie,由于这个cookie设置在了这个页面 //cookie.Domain = ".rupeng.com"; //把这个cookie设置在了这个域名 www.rupeng.com和bbs.rupeng.com是同一个域名下的2个不一样网站,其cookie若是不设置,是不共用的 context.Response.SetCookie(cookie); } public bool IsReusable { get { return false; } } }
public class cookiePath2 : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; //读取cookie HttpCookie cookie = context.Request.Cookies["path"]; context.Response.Write(cookie == null ? "没有cookie" : cookie.Value + "||" + cookie.Path); } public bool IsReusable { get { return false; } } }
4 Session的写入和读取,以及判断登陆用户是否有权限asp.net
session存在服务器,用一个没法被篡改的“身份证号”的sessionId惟一标示。
session必须实现IRequiresSessionState接口,可是会影响性能。
cookie只能存字符串,session几乎能够存任意类型。
session与cookie相关,默认也是浏览器关闭就消失,能够经过<sessionState timeout="20" />在web.config中设置超时时间20分钟。(超时没效果)
public class session1 : IHttpHandler,IRequiresSessionState { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; //写入session context.Session["session1"] = "ruepng.com"; context.Session["session2"] = 888; } public bool IsReusable { get { return false; } } }
public class session2 : IHttpHandler, IRequiresSessionState { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; object session1 = context.Session["session1"]; //string类型 object session2 = context.Session["session2"]; //int类型 context.Response.Write(session1 == null ? "没有这个session" : session1.ToString()); context.Response.Write(session2 == null ? "没有这个session2" :session2); } public bool IsReusable { get { return false; } } }
判断登陆用户是否有权限
public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/html"; string login = context.Request["login"]; string html = CommonHelper.GetHtmlFromVirtualPath(context, "~/Day4/sessionUserName.html"); #region 展现 if (string.IsNullOrWhiteSpace(login)) //展现 { HttpCookie cookieUserName = context.Request.Cookies["LastUserName"]; if (cookieUserName != null) { html = html.Replace("@username", cookieUserName.Value); context.Response.Write(html); } else { html = html.Replace("@username", ""); context.Response.Write(html); } } #endregion #region 登陆 else //登陆 { string username = context.Request["username"]; string password = context.Request["password"]; if (password == "123") //为了方便后面的权限判断 username是否为admin,因此这里没注明 { //写入cookie 方便下次登陆时自动填充 HttpCookie cookie = new HttpCookie("LastUserName"); cookie.Value = username; cookie.Expires = DateTime.Now.AddDays(7); context.Response.SetCookie(cookie); //写入session 方便后面权限判断 context.Session["LastUserName"] = username; //与cookie相关,默认也是关闭浏览器就消失 } else { //登陆失败 context.Response.Redirect("sessionUserName.ashx"); } } #endregion } public bool IsReusable { get { return false; } }
<body> <form action="sessionUserName.ashx" method="post"> 用户名<input type="text" name="username" value="@username" /><br /> 密码<input type="password" name="password" value="" /><br /> <input type="submit" name="login" value="登陆" /><br /> </form> </body>
public class sessionUserName1 : IHttpHandler, IRequiresSessionState { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; //从session中判断是否有访问权限 object sessionUserName = context.Session["LastUserName"]; if (sessionUserName!=null && sessionUserName.ToString() == "admin") //假设登陆user为admin就有权限 { context.Response.Write("能够继续这个页面"); } else { context.Response.Write("该用户未登陆或者没有权限"); } } public bool IsReusable { get { return false; } } }
5 实现登陆后 返回进入登陆的页面
登陆时把username存入session中,进入其余页面时判断该sessionId是否为null。
要想登陆后跳转之前的页面,须要在之前的页面把url存入session。
要想注销退出登陆,须要Abandon()。
using Console_Core.BLL; using Console_Core.Common; using Console_Core.Model; using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.SessionState; namespace Web_Cassini.Day4.SessionCase { /// <summary> /// lojin 的摘要说明 /// </summary> public class lojin : IHttpHandler,IRequiresSessionState { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/html"; string login = context.Request["login"]; string html = CommonHelper.GetHtmlFromVirtualPath(context, "~/Day4/SessionCase/lojin.html"); if(string.IsNullOrWhiteSpace(login)) //展现 { html = html.Replace("@username", "").Replace("@password", "").Replace("{msg}", ""); context.Response.Write(html); } else //登陆 { string username = context.Request["username"]; string password = context.Request["password"]; //根据username判断 List<object> list = new MyORM_BLL().SelectModelByField(typeof(TC_STUDENT), "USERNAME='" + username + "'"); if (list.Count <= 0) //登陆失败 { html = html.Replace("@username", "").Replace("@password", "").Replace("{msg}", "用户名不存在"); context.Response.Write(html); } else if (list.Count == 1) //成功 { context.Session[MySessionClass.LOGINUSERNAME] = username; //context.Response.Redirect("modifypwd.ashx"); //context.Response.Redirect("queryyue.ashx"); string LoginBeforeUrl = (string)context.Session[MySessionClass.LOGINBEFOREURL]; if (LoginBeforeUrl != null) { context.Response.Redirect(LoginBeforeUrl); } else { context.Response.Write("登陆成功"); } } else { throw new Exception("内部服务器出错:存在重复的username="+username+"的数据"); } } } public bool IsReusable { get { return false; } } } }
<body> <form action="lojin.ashx" method="post"> 用户名<input type="text" name="username" value="@username" /><span>{msg}</span><br /> 密码<input type="password" name="password" value="@password" /><br /> <input type="submit" name="login" value="登陆" /><br /> </form> </body>
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.SessionState; namespace Web_Cassini.Day4.SessionCase { /// <summary> /// modifypwd 的摘要说明 /// </summary> public class modifypwd : IHttpHandler, IRequiresSessionState { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/html"; string username = (string)context.Session[MySessionClass.LOGINUSERNAME]; if (username != null) { context.Response.Write("Hello World 修改密码:" + username + " ......<a href=\"exit.ashx\">退出登陆</a>"); } else { //为了使登陆成功后,返回之间进入的页面,须要把以前的url存入session中 context.Session[MySessionClass.LOGINBEFOREURL] = context.Request.Url.ToString(); context.Response.Redirect("lojin.ashx"); } } public bool IsReusable { get { return false; } } } }
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.SessionState; namespace Web_Cassini.Day4.SessionCase { /// <summary> /// queryyue 的摘要说明 /// </summary> public class queryyue : IHttpHandler, IRequiresSessionState { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/html"; string username = (string)context.Session[MySessionClass.LOGINUSERNAME]; if (username != null) { context.Response.Write("Hello World 查询余额:" + username+" ......<a href=\"exit.ashx\">退出登陆</a>"); } else { context.Session[MySessionClass.LOGINBEFOREURL] = context.Request.Url.ToString(); context.Response.Redirect("lojin.ashx"); } } public bool IsReusable { get { return false; } } } }
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.SessionState; namespace Web_Cassini.Day4.SessionCase { /// <summary> /// eixt 的摘要说明 /// </summary> public class exit : IHttpHandler, IRequiresSessionState { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; context.Session.Abandon(); context.Response.Redirect("lojin.ashx"); } public bool IsReusable { get { return false; } } } }
6 验证码
要想生成验证码,须要生成一个图片保存到输出流(即显示到页面),并使它能够被刷新。
要想验证验证码,须要在生成时存入session,在登陆时判断输出的验证码是否与session中验证码相同,若是不一样就是验证失败。
public void ProcessRequest(HttpContext context) { context.Response.ContentType = "image/jpeg"; Random dom = new Random(); int num = dom.Next(1000, 10000); string code = num.ToString(); context.Session[MySessionClass.VOLIDECODE] = code; using (Bitmap map = new Bitmap(60, 20)) { using (Graphics g = Graphics.FromImage(map)) using (Font font = new Font(FontFamily.GenericSerif, 15)) { g.DrawString(code, font, Brushes.Red, 0, 0); } map.Save(context.Response.OutputStream, ImageFormat.Jpeg); } }
登陆验证时的主要代码:
//验证 验证码 string volidcode=context.Request["volidcode"]; string volidcodeInSesion = (string)context.Session[MySessionClass.VOLIDECODE]; if (volidcode!=volidcodeInSesion) { html = html.Replace("{msg}", "验证码错误"); context.Response.Write(html); return; }
7 session根本原理:
本身写的session--> YangGuoSessionID
初始化YangGuoSessionID.cs时,判断cookie中是否有YangGuoSessionID,若是有就得到sessionId的值,若是没有就建立一个sessionId并得到值;
当设值(写入)时,就是把值写入sessionId所表示的文件中;
当取值(读取)时,就是去除当前sessionId文件中的值。
同时,为了使自定义的YangGuoSessionID能够写入多个值,能够将须要写入的内容以键值对的形式序列化到文件中;读取时,从文件中反序列化为键值对。
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.Serialization.Formatters.Binary; using System.Web; namespace Web_Cassini.Day4.SessionCase { public class YangGuoSessionID { public const string YANGGUOSESSIONID = "YangGuoSessionID"; private HttpContext context; private string sessionId; public YangGuoSessionID(HttpContext context) { this.context = context; GetYangGuoSessionID(); } /// <summary> /// 建立自定义sessionId /// </summary> /// <returns>返回自定义cookie的值</returns> private string CreateYangGuoSessionID() { Guid guid = Guid.NewGuid(); HttpCookie cookie = new HttpCookie(YANGGUOSESSIONID); cookie.Value = guid.ToString(); context.Response.SetCookie(cookie); return cookie.Value; } /// <summary> /// 得到YangGuoSessionID /// </summary> /// <returns>返回YangGuoSessionID的值</returns> public void GetYangGuoSessionID() { HttpCookie cookie = context.Request.Cookies[YANGGUOSESSIONID]; if (cookie == null) //判断cookie中是否有YangGuoSessionID,没有就建立,有就得到 { this.sessionId = CreateYangGuoSessionID(); } else { this.sessionId = cookie.Value; } } /// <summary> /// 设置自定义sessionId中的name的value /// </summary> /// <param name="name">须要保存的name</param> /// <param name="value">须要保存的对应name的value</param> public void SetValue(string name, string value) { string path = context.Server.MapPath("~/Day4/SessionCase/" + this.sessionId); Dictionary<string, string> dict = new Dictionary<string, string>(); BinaryFormatter bf = new BinaryFormatter(); if (File.Exists(path)) { //先将文件中的内容反序列化为键值对 dict = Deserialize(path); } //更新键值对后 dict[name] = value; //再序列化到文件中 using (Stream s = File.OpenWrite(path)) { bf.Serialize(s, dict); } } /// <summary> /// 得到自定义的sessionId的对应name的值 /// </summary> /// <param name="name">须要查询的name</param> /// <returns>sessionId对应文件中对应name的value</returns> public string GetValue(string name) { string path = context.Server.MapPath("~/Day4/SessionCase/" + this.sessionId); if (File.Exists(path)) { //先将文件中的内容反序列化为键值对 Dictionary<string, string> dict = Deserialize(path); if (dict.ContainsKey(name)) { return dict[name]; } else { return null; } } else { return null; } } /// <summary> /// 将路径path中内容反序列化为键值对 /// </summary> /// <param name="path">w=文件路径</param> /// <returns>键值对</returns> public Dictionary<string, string> Deserialize(string path) { //先将文件中的内容反序列化为键值对 BinaryFormatter bf = new BinaryFormatter(); using (Stream s = File.OpenRead(path)) { return (Dictionary<string, string>)bf.Deserialize(s); } } ///// <summary> ///// 设置session的值时,把值保存到sesionId对应的文件 ///// </summary> ///// <param name="value">要设置的session的值</param> //public void SetValue(string value) //{ // string path = context.Server.MapPath("~/Day4/SessionCase/" + this.sessionId); // File.WriteAllText(path, value); //} ///// <summary> ///// 得到session的值 ///// </summary> ///// <returns>从sessionId对应文件中得到的值</returns> //public string GetValue() //{ // string path = context.Server.MapPath("~/Day4/SessionCase/" + this.sessionId); // if (File.Exists(path)) // { // return File.ReadAllText(path); // } // else // { // return null; // } //} } }
public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; //写入session YangGuoSessionID ygsesion = new YangGuoSessionID(context); //ygsesion.SetValue("yangguo"); ygsesion.SetValue("username", "yzk"); ygsesion.SetValue("时间", DateTime.Now.ToString()); }
public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; YangGuoSessionID ygsession = new YangGuoSessionID(context); //string str = ygsession.GetValue(); //context.Response.Write(str); string username =ygsession.GetValue("username"); string date = ygsession.GetValue("时间"); context.Response.Write(username + "===" + date); }
8 配置进程外Session:
(1)将服务器Session信息存储在进程外
<1> 首 先,开启asp.net state 服务: 控制面板 -> 程序和功能 -> “打开或者关闭 Windows 功能”对话框 -> Internet 信息服务 -> 万维网服务 -> 应用程序开发功能 -> ASP.NET。(Control Panel -> Programs - > Programs and Features -> Turn Windows features on or off - > Internet Information Services -> World Wide Web Services -> Application Development Features -> ASP.NET。)
勾选 ASP.NET 选项后,在 Control Panel -> System and Security -> Administrative Tools -> Services 服务中就会出现 ASP.NET State Service 服务。
在属性对话框中设置启动类型为自动(Automatic),最后启动。(备注:Windows XP 系统是在控制面板中的“添加和删除程序”中设置)
<2> 而后,回到Web.config文件中上述的段落中,将mode的值改成StateServer。
<sessionState mode="StateServer" stateConnectionString="tcpip=127.0.0.1:42424" timeout="20"></sessionState>
保存文件后的从新打开一个IE,打开 SessionState.aspx页面,保存一些信息到Session中。这时,让咱们重起IIS,再回到SessionState.aspx页面中查 看刚才的Session信息,发现没有丢失。 实际上,这种将Session信息存储在进程外的方式不光指能够将信息存储在本机的进程外,还能够将Session信息存储在其余的服务器的进程中。 这时,不光须要将mode的值改成StateServer,还须要在stateConnectionString中配置相应的参数。例如你的计算你是 192.168.0.1,你想把Session存储在IP为192.168.0.2的计算机的进程中,就须要设置成这 样:stateConnectionString="tcpip=192.168.0.2:42424"。固然,不要忘记在192.168.0.2的计算 机中装上.NET Framework,而且启动ASP.NET State Services服务。 (2)将服务器Session信息存储在SQL Server中 <1>首先,仍是让咱们来作一些准备工做。启动SQL Server和SQL Server代理服务。在SQL Server中执行一个叫作InstallSqlState.sql的脚本文件。这个脚本文件将在SQL Server中建立一个用来专门存储Session信息的数据库,及一个维护Session信息数据库的SQL Server代理做业。咱们能够在如下路径中找到那个文件: [system drive]\winnt\Microsoft.NET\Framework\[version]\ 而后打开查询分析器,链接到SQL Server服务器,打开刚才的那个文件而且执行。稍等片刻,数据库及做业就创建好了。这时,你能够打开企业管理器,看到新增了一个叫ASPState的 数据库。可是这个数据库中只是些存储过程,没有用户表。实际上Session信息是存储在了tempdb数据库的 ASPStateTempSessions表中的,另一个ASPStateTempApplications表存储了ASP中Application对 象信息。这两个表也是刚才的那个脚本创建的。另外查看管理->SQL Server代理->做业,发现也多了一个叫作ASPState_Job_DeleteExpiredSessions的做业,这个做业实际上就是 每分钟去ASPStateTempSessions表中删除过时的Session信息的。 <2>接着,咱们返回到Web.config文件,修改mode的值改成SQLServer。注意,还要同时修改sqlConnectionString的值,格式为: sqlConnectionString="data source=localhost; Integrated Security=SSPI;" 其中data source是指SQL Server服务器的IP地址,若是SQL Server与IIS是一台机子,写127.0.0.1就好了。Integrated Security=SSPI的意思是使用Windows集成身份验证,这样,访问数据库将以ASP.NET的身份进行,经过如此配置,可以得到比使用 userid=sa;password=口令的SQL Server验证方式更好的安全性。固然,若是SQL Server运行于另外一台计算机上,你可能会须要经过Active Directory域的方式来维护两边验证的一致性。 一样,让咱们作个试验。向SessionState.aspx中添加Session信息,这时发现Session信息已经存在SQL Server中了,即便你重起计算机,刚才的Session信息也不会丢失。如今,你已经彻底看见了Session信息究竟是什么样子的了,并且又是存储 在SQL Server中的,能干什么就看你的发挥了