不拖控件ASP.NET—探知cookie和session(1)

1.      为什么会出现cookie和session?

?  先看一个例子:

    我们还是使用之前的NVelocity,不清楚的参看链接:http://blog.csdn.net/u010955843/article/details/42977533,同样建立commonhelper类,里面封装NVelocity模板,并且建立html也作为渲染的模板进行显示。

     html页

<span style="font-family:Microsoft YaHei;"><strong><strong><span style="font-family:Microsoft YaHei;font-size:14px;"><!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="../zhuangtaibaochiHttpNoState.ashx" method="get">
        <input type="submit" value="增加" />
        <p>$Model.Count</p>
    </form>
</body>
</html>
</span></strong></strong></span>

一般处理程序

<span style="font-family:Microsoft YaHei;"><strong><strong><span style="font-family:Microsoft YaHei;font-size:14px;">using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace zhuangtaibaochi
{
    /// <summary>
    /// zhuangtaibaochiHttpNoState 的摘要说明
    /// </summary>
    public class zhuangtaibaochiHttpNoState : IHttpHandler
    {
        private int  i=1;

        public void ProcessRequest(HttpContext context)
        {

            context.Response.ContentType = "text/html";
            context.Response.Write("Hello World");
            i++;
            string html = commonHelper.RenderHtml("HttpNozhuangtai.html",new{ Count=i});
            context.Response.Write(html);

        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}</span></strong></strong></span>

commonhelper修改一处即可,其实可以不改,自己设计的填充模板的数据的名字,可以随便设计

<span style="font-family:Microsoft YaHei;"><strong><strong><span style="font-family:Microsoft YaHei;font-size:14px;">using NVelocity;
using NVelocity.App;
using NVelocity.Runtime;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace zhuangtaibaochi
{
    public class commonHelper
    {
        /// <summary>
        /// 用data数据填充templateName模板,渲染生成html返回
        /// </summary>
        /// <param name="templateName">模板名字</param>
        /// <param name="data">填充模板数据</param>
        /// <returns></returns>
        public static string RenderHtml(string templateName, object data)
        {
            VelocityEngine vltEngine = new VelocityEngine();
            vltEngine.SetProperty(RuntimeConstants.RESOURCE_LOADER, "file");
            vltEngine.SetProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, System.Web.Hosting.HostingEnvironment.MapPath("~/templates"));//模板文件所在的文件夹,我们遵从上次讲的我们还是放在templates这个文件夹中,自己也可以新建别的名字的
            vltEngine.Init(); //引擎初始化

            VelocityContext vltContext = new VelocityContext();
            vltContext.Put("Model", data);//设置参数,在模板中可以通过$data来引用

            Template vltTemplate = vltEngine.GetTemplate(templateName);//渲染的html模板
            System.IO.StringWriter vltWriter = new System.IO.StringWriter();
            vltTemplate.Merge(vltContext, vltWriter);

            string html = vltWriter.GetStringBuilder().ToString();
            return html;
        }
    }
}</span></strong></strong></span>

      我们发现即使每次点击增加按钮,数字2都不会改变,原因在于http协议是无状态的。可以自己试试。

?  再看一个例子:通过隐藏字段让http记住状态

      同上例,只是修改html页和一般处理程序,commhelper不需要改变

     html页

<span style="font-family:Microsoft YaHei;"><strong><strong><span style="font-family:Microsoft YaHei;font-size:14px;"><!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>
    <title></title>
</head>
<body>
    <form action="HtttpNoZhuangTai.ashx" method="get">
        <input type="submit" value="增加" />
        <input type="hidden" name="Count" value="$Model.Count" />
        <p>$Model.Count</p>
    </form>
</body>
</html>
</span></strong></strong></span>

一般处理程序,只是修改ProcessRequest方法

<span style="font-family:Microsoft YaHei;"><strong><strong><span style="font-family:Microsoft YaHei;font-size:14px;"> private int  i=1;

        public void ProcessRequest(HttpContext context)
        {

            context.Response.ContentType = "text/html";
            //context.Response.Write("Hello World");
            //i++;
            //string html = commonHelper.RenderHtml("HttpNozhuangtai.html",new{ Count=i});
            //context.Response.Write(html);
            //从病历本读出上次的值
            int count = Convert.ToInt32(context.Request["Count"]);
            count++;
            //新的值写入病历本
            string html = commonHelper.RenderHtml("HttpNozhuangtai.html", new { Count = count });
            context.Response.Write(html);
        }</span></strong></strong></span>

      此时当我们点击的时候发现实现了每次数目的递增,这是因为我们将值存储在了隐藏字段里面,这样需要的时候可以方便地调出来。比如我们可以把客户端假定为病人,服务端看成是医生,我们知道当医生诊断完一个患者,会给病人一个病历本,这样下次来看的时候就会根据上次的诊断情况来确定这次如何去诊断,让客户端(病人)帮你保存字段,此时隐藏字段相当于病历本,隐藏字段记住了之前的状态,当需要的时候再次调出,这样就实现了数据递增。

      但是我们因为是get提交,用户是可以更改信息,这样就会出现信息的不安全性,所以存放在客户端的必须是用户更改之后页无所谓的,否则存在很大的问题。

?  无状态http协议简介

     http协议是无状态的,不会记得上次和网页“发生了什么”。服务器不记的上次给了浏览器什么,否则服务器的压力太大,浏览器需要记住这些值,下次再提交服务器的时候,就要把上次的值交给服务器,让他想起来。如果要知道上一次的状态,一个方法是在对浏览器响应结束之前将状态信息保存到页面表单总(实现一下),下次页面再向服务器发出请求的时候带上这些状态信息,这样服务器就能根据这些状态信息还原上次的状态了,类似于去看病的病历本。

      尽量不要这么干(将信息存储在服务端),客户端的事情让客户端去做。

      状态信息保存在隐藏字段中的缺点:加大网站的流量、降低访问速度、机密数据放到表单中会有数据欺骗等安全性问题。

2.      Cookie

      隐藏字段实现不了自由传递数据和读取数据,只有需要时候发送请求,之后服务器再响应。故而cookie应运而生。

?  什么是cookie?

      如果想要实现自由的传递和读取,用cookie。Cookie是和站点相关的,并且每次向服务器请求的时候除了发送表单参数外,还会将和站点相关的所有的cookie都提交给服务器,是强制性的。Cookie也是保存在浏览器端的,而且浏览器会在每次请求的时候都会把和这个站点相关的cookie提交到服务器,并且将服务端返回的cookie更新回数据库,因此可以将信息保存在cookie中,然后在服务器端读取和修改。服务器返回数据除了普通的html数据以外,还会返回修改的cookie,浏览器把拿到的cookie值更新本地浏览器的cookie就可以。

      此外存到浏览器中,也就是本地电脑中,是可读可写的,只有网站自己可以读写的,别人是读不了的,避免了隐私外泄的安全隐患。也就是与域名(域名不同,网站不同)相关的,本地域名或者自己的域名才能读,谁写谁读;存到本地硬盘中,浏览器通过报文字段发过去,每次向服务器请求,都会发送cookie,浏览器在后台通过报文字段进行发送。

?  示例

    新建一般处理程序名为cookieTest.ashx

<span style="font-family:Microsoft YaHei;"><strong><strong><span style="font-family:Microsoft YaHei;font-size:14px;">using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace zhuangtaibaochi
{
    /// <summary>
    /// cookieTest 的摘要说明
    /// </summary>
    public class cookieTest : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/html";
            //context.Response.Write("Hello World");
            string read=context.Request["Read"];
            if (!string.IsNullOrEmpty(read))
            {
                HttpCookie cookie = context.Request.Cookies["Age"];
                string value = cookie.Value;
                var data = new { Value = value };
                string html = commonHelper.RenderHtml("cookieTest.html", data);
                context.Response.Write(html);
            }
            else if (!string.IsNullOrEmpty(context.Request["Write"]))
            {
                context.Response.SetCookie(new HttpCookie("Age", "33"));
                string html = commonHelper.RenderHtml("cookieTest.html", null);
                context.Response.Write(html);

            }
            else
            {
                string html = commonHelper.RenderHtml("cookieTest.html", null);
                context.Response.Write(html);
            }
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}</span></strong></strong></span>

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="../cookieTest.ashx" method="post">

<input type="submit" name="Read" value="读" />

<input type="submit" name="Write" value="写" />

读出来的cookie:$Model.Value

</form>

</body>

</html>

     commonhelper同上面的

      这样我们便可以读取cookie的值。

?  报文分析

     运行程序,并且打开firebug(火狐浏览器)其他浏览器中快捷键F12或者工具菜单下面的开发人员工具均可以查看。

此时刷新页面可以看到我们发送的请求:

     这时候我们可以点击写,因为此时没有cookie我们需要存入一个cookie

此时设置课cookie,存在浏览器的某个地方;下次再发请求的时候直接读取cookie即可,此时执行的是处理程序的读方法,也就是可以在服务器端通过request.cookie进行获取了。此时点击读显示

     Cookie在客户端是以键值对的形式存在的,告诉cookie进行存储

      点击写按钮的时候执行写进一个cookie,当点击读的时候将所存储的cookie进行读出来的操作,读取的时候通过报文进行读取,利用报文进行读取的和传递的

?  限制

     Cookie的缺点是不能存储过多的信息,机密信息不能存;Cookie无法跨不同的浏览器,Cookie存在客户端,故而存在安全性的问题,cookie是可以被清除的,不能把不能丢的数据存到cookie中;cookie尺寸有限制,一般为几k或者几百k。

     如何清除Cookis,我们以ie为例

   
  点击工具—Internet选项

      点击删除时显示

?  过期问题

      浏览器关闭之后那么cookie就会过期不再存在(默认情况下),如何使得浏览器关闭之后仍可以存在呢?

      设置过期日期是一天后的,也就是一天后的这个时间

     在上述的例子上修改cookieTest.ashx中的部分代码即可

<span style="font-family:Microsoft YaHei;"><strong><strong><span style="font-family:Microsoft YaHei;font-size:14px;">else if (!string.IsNullOrEmpty(context.Request["Write"]))
            {
                //SetCookie(new HttpCookie("Age", "33")) Cookie生命周期是浏览器的生命周期
                //浏览器重启就自动删除了
                //context.Response.SetCookie(new HttpCookie("Age", "33"));
                HttpCookie cookie1 = new HttpCookie("Age", "33");
                cookie1.Expires = DateTime.Now.AddDays(1);
                context.Response.SetCookie(cookie1);
                context.Response.SetCookie(new HttpCookie("Name", "yzk"));
                string html = commonHelper.RenderHtml("cookieTest.html", null);
                context.Response.Write(html);

            }
            else
            {
                string html = commonHelper.RenderHtml("cookieTest.html", null);
                context.Response.Write(html);
            }</span></strong></strong></span>

      此时点击写查看报文信息,看到了服务器端响应的被设置的cookie以及过期日期,过期之后的新的cookie

      如果浏览器满了就会根据优先级或者最先存的删除掉了,过期时间是最多,并不是肯定就是那个日期。

      不设置cookie的失效时间,默认的就是关闭浏览器就会使得其失效,这样都不安全,因为客户端用户可以修改cookie的值。Cookie相当于病历本,写到病历本,用户不会篡改cookie。也就是用户不会篡改病历本(把自己的病情写成别的,但是不一定),也就是存在修改,是不安全的。同时用户会担心医生修改病历本,故而这样写到病历本上的信息就不安全。如何防止病人修改或者医生修改或者家属修改修改病历本呢?

      Cookie不能存储机密数据,如果想保存机密数据,可以保存一个Guid(全局唯一标识符(GUID,Globally Unique Identifier)也称作 UUID(Universally Unique IDentifier) 。GUID是一种由算法生成的二进制长度为128位的数字标识符。GUID主要用于在拥有多个节点、多台计算机的网络或系统中。在理想情况下,任何计算机和计算机集群都不会生成两个相同的GUID。GUID
的总数达到了2^128(3.4×10^38)个,所以随机生成两个相同GUID的可能性非常小,但并不为0。)到Cookie中,然后在服务器端建建立一个以Guid为Key,复杂数据为Value全局Dictionary。

3.      总结

    存到客户端浏览器是很容易修改的,故而存在安全隐患,所以引出来了服务器端的机制,那就没有办法修改了,故而服务器端的数据安全性较客户端好的多,并且在其他的页面也能取到数据。

    下篇博客我们将继续进行另一种较为安全的服务器端的机制那就是session的讲解,请继续关注~

时间: 2024-10-13 18:50:03

不拖控件ASP.NET—探知cookie和session(1)的相关文章

不拖控件ASP.NET——探知cookie和session(2)

    接着上篇的博客我们来讲解服务器端保存数据的机制-session     我们知道cookie是保存在客户端的,这样数据就存在一个不安全性,此外还有 一个问题就是不能够存储大量的数据,我们上篇博客还遗留一个问题就是客户端是可以篡改数据的,相当于保留在病人手上的病历本是可能被用户篡改的(一般情况下,用户不会篡改,这样多危险了,医生误诊怎么办?哈哈)     此外医生会给每个患者编制一个编号,并且自己再保存一个编号,这样当病人来的时候根据编号来识别病人的身份,当然用户会可以别人的编号猜出来自己

不拖控件ASP.NET——一般处理程序

    习惯了微软提供的一系列Web控件,用着很方便,最近看了一种新的方式不用拖控件就能实现同样的功能,究竟拖控件好还是不拖控件好,随着以后学习的深入,答案会慢慢揭晓,希望一直关注哦!今天我们来看看一般处理程序. 1.      一般处理程序(HttpHandler) ?  引入     我们从一个网站打开的流程讲起.如下图:     流程细说:用webForm开发一个模拟的登陆页面,用户打开登陆页面,填入相应的用户信息:用户名和密码,点击[登陆]按钮,浏览器将用户名和密码发送给网站服务器,网站

不拖控件ASP.NET——NVelocity(2)

    上节课我们讲述了NVelocity的简单应用,但是没有和数据库打交道,这次我们来和数据库连接实现人员的增删改查. 1.      上篇博客回顾     链接:http://blog.csdn.net/u010955843/article/details/42528761     开讲之前,我们先来回顾上一节课讲的内容,主要是两个页面,一个是一般处理程序的页面,另一个是渲染后的模板. ?  机制     上篇博客中我们建立一个person类,并且在一般处理程序中对其进行了赋值,之后交给了模

不拖控件ASP.NET——NVelocity(1)

    模板引擎(这里特指用于Web开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的HTML文档.今天我们主要来介绍NVelocity模板引擎 1. NVelocity基础 ?  定义     NVelocity是一个基于.NET的模板引擎(template engine).它允许任何人仅仅简单的使用模板语言(template language)来引用由.NET代码定义的对象.从而使得界面设计人员与.NET程序开发人员

不拖控件的asp.net编程方法——第1回

以前写的asp.net程序基本上都用了webfrom的控件编写的,当然有个好处就是易入门.快速效率高,但感觉自己这了几个小系统,还是没学到什么东西,感觉心里没底,因为都是封装好的东西,拿来就用的,功能能实现,但原理性的东西不明白,所以遇到有些错误根本无从下手,虽然貌似很多公司开发都有控件,但作为学生个人觉得还是别用好,当然那些自定义控件的又另当别论. 本想深入研究asp.net MVC,但发现不懂的知识太多了,所以现在暂时先学HTML+ashx这样的形式,换成这种形式写还真不习惯,下面把我今天学

【Visual Basic】纯代码不拖控件,利用动态生成控件的方式完成一个简单的四则运算计算器

vb6是一个典型的拖控件加代码的编程代表,因此也一直被认为难登大雅之堂,但是,在vb6中可以完全纯粹地使用代码控制这个窗体与窗体的控件.这样生成出来的控件位置摆放精确无比,无须拖好控件之后,再利用工具栏的"格式"菜单慢慢地调整大小.这种方式的确定是声明一个控件要耗费大量的代码,但其实Java中的Swing,HTML+CSS排放控件,比这好不了多少. 当然,比vc6中mfc的代码简单了不少,具体见<[mfc]基本对话框程序--加法器>(点击打开链接) 一.基本目标 利用纯粹代

ASP.NET控件&lt;ASP:Button /&gt; html控件&lt;input type=&quot;button&quot;&gt;区别联系

ASP.NET控件<ASP:Button />-------html控件<input type="button">杨中科是这么说的:asp和input是一样的东西 服务器只认识input,我们可以直接写input 但是asp是要把自己自动翻译成input再交给服务器的.其实是一样的东西 写写我看到的区别:                asp控件,直接可以用c#编程                input加上 runat=“server” 也被c#编程了 说白

【实战项目】【FLEX】#900 实现拖控件功能

一.功能说明:拖控件的功能(类似FLEX,VS 里面的拖控件). 提示:大家对事件的注册和派发的说法可能不一样.因为在FLEX中和在Java中,叫法有的区别.但是本质是一样的. 注册事件  == 设置监听事件    ||       派发事件 == 触发事件  ,也有人叫 “进行广播”            大家知道什么意思就好.   说明: 1.Application页面(放置控件列表,页面容器,属性面板这三个模块的Application页面)[PS:以下简称:主页面 ] 1.1  主页面加载

文件上传控件asp:FileUpload

前端 使用的控件<asp:FileUpload ID="fileup" runat="server" /><span class="message">*</span> $("#btn_Save_").click(function () { var url = "Upload.aspx?_method=import";// url += "&_method