C#中关于Cookie的理解

本文链接出自:https://www.cnblogs.com/xiangzhe-C/p/4230042.html

1、Cookie简介

  Cookie 提供了一种在 Web 应用程序中存储用户特定信息的方法。例如,当用户访问您的站点时,您可以使用 Cookie 存储用户首选项或其他信息。当该用户再次访问您的网站时,应用程序便可以检索以前存储的信息。

  用户在请求站点中的页面时应用程序发送给该用户的不仅仅是一个页面,还有一个包含日期和时间的 Cookie,用户的浏览器在获得页面的同时还获得了该 Cookie,并将它存储在用户硬盘上的某个文件夹中。以后,如果该用户再次请求您站点中的页面,当该用户输入 URL 时,浏览器便会在本地硬盘上查找与该 URL 关联的 Cookie。如果该 Cookie 存在,浏览器便将该 Cookie 与页请求一起发送到您的站点。然后,应用程序便可以确定该用户上次访问站点的日期和时间。您可以使用这些信息向用户显示一条消息,也可以检查到期日期。

  Cookie 与网站关联,而不是与特定的页面关联。因此,无论用户请求站点中的哪一个页面,浏览器和服务器都将交换 Cookie 信息。用户访问不同站点时,各个站点都可能会向用户的浏览器发送一个 Cookie;浏览器会分别存储所有 Cookie。

2、Cookie 的限制

  大多数浏览器支持最大为 4096 字节的 Cookie。浏览器还限制站点可以在用户计算机上存储的 Cookie 的数量。大多数浏览器只允许每个站点存储 20 个 Cookie;如果试图存储更多 Cookie,则最旧的 Cookie 便会被丢弃。有些浏览器还会对它们将接受的来自所有站点的 Cookie 总数作出绝对限制,通常为 300 个。

3、编写 Cookie

3.1、简单Cookie

  浏览器负责管理用户系统上的 Cookie。Cookie 通过 HttpResponse 对象发送到浏览器,该对象公开称为 Cookies 的集合。可以将 HttpResponse 对象作为 Page 类的 Response 属性来访问。要发送给浏览器的所有 Cookie 都必须添加到此集合中。创建 Cookie 时,需要指定 NameValue。每个 Cookie 必须有一个唯一的名称,以便以后从浏览器读取 Cookie 时可以识别它。由于 Cookie 按名称存储,因此用相同的名称命名两个 Cookie 会导致其中一个 Cookie 被覆盖。

  还可以设置 Cookie 的到期日期和时间。用户访问编写 Cookie 的站点时,浏览器将删除过期的 Cookie。只要应用程序认为 Cookie 值有效,就应将 Cookie 的有效期设置为这一段时间。如果没有设置 Cookie 的有效期,仍会创建 Cookie,但不会将其存储在用户的硬盘上。而会将 Cookie 作为用户会话信息的一部分进行维护。当用户关闭浏览器时,Cookie 便会被丢弃。

//写入一个Cookie
//法1:
Response.Cookies["userName"].Value = "Jack";
Response.Cookies["userName"].Expires = DateTime.Now.AddDays(1);
//法2:
HttpCookie cookie= new HttpCookie("User");
cookie.Value = "Ruth.";
cookie.Expires = DateTime.Now.AddDays(1);//设置Cookie的有效时间,若不设置则在关闭浏览器后自动清除
cookie.HttpOnly = true;//将cookie设置成HttpOnly是为了防止XSS攻击,窃取cookie内容,这样就增加了cookie的安全性
Response.Cookies.Add(cookie);
//Response.AppendCookie(cookie);//也可使用此方法添加Cookie的值
编写简单Cookie

3.2、多值Cookie

  可以在一个 Cookie 中存储多个名称/值对。名称/值对称为子键。(子键布局类似于 URL 中的查询字符串。)

  带有子键的 Cookie 还可帮助您限制 Cookie 文件的大小。正如前面“Cookie 的限制”一节中所提到的,Cookie 通常限制为 4096 字节,并且每个站点最多可存储 20 个 Cookie。使用带子键的单个 Cookie,使用的 Cookie 数就不会超过分配给站点的 20 个的限制。此外,一个 Cookie 会占用大约 50 个字符的系统开销(用于保存有效期信息等),再加上其中存储的值的长度,其总和接近 4096 字节的限制。如果存储五个子键而不是五个单独的 Cookie,便可节省单独 Cookie 的系统开销,节省大约 200 字节。

//写入多个值存放于Cookie
//法1:
Response.Cookies["userInfo"]["userName"] = "Jack";
Response.Cookies["userInfo"]["PWD"] = "123";
Response.Cookies["userInfo"].Expires = DateTime.Now.AddDays(1);
//法2:
HttpCookie cookie= new HttpCookie("userInfo");
cookie.Values["userName"] = "Jack";
cookie.Values["PWD"] = "123";
cookie.Expires = DateTime.Now.AddDays(1);//设置Cookie的有效时间
cookie.HttpOnly = true;//将cookie设置成HttpOnly是为了防止XSS攻击,窃取cookie内容,这样就增加了cookie的安全性
Response.Cookies.Add(cookie);
//Response.AppendCookie(cookie);
多值Cookie

3.3、控制 Cookie 的范围

  默认情况下,一个站点的全部 Cookie 都一起存储在客户端上,而且所有 Cookie 都会随着对该站点发送的任何请求一起发送到服务器。也就是说,一个站点中的每个页面都能获得该站点的所有 Cookie。但是,可以通过两种方式设置 Cookie 的范围:

HttpCookie appCookie = new HttpCookie("User");
appCookie.Value = "Jack " ;
appCookie.Expires = DateTime.Now.AddDays(1);
appCookie.Path = "/Application1";//将 Cookie 的范围限制到服务器上的某个文件夹,这允许您将 Cookie 限制到站点上的某个应用程序。
appCookie.Domain = "support.contoso.com";//将范围设置为某个域,这允许您指定域中的哪些子域可以访问 Cookie。
//或者appCookie.Domain = "contoso.com";//以此方式设置域时,随后 Cookie 将可用于主域,也可用于 sales.contoso.com 和 support.contoso.com 域。
Response.Cookies.Add(appCookie);
控制Cookie的范围

  路径可以是站点根目录下的物理路径,也可以是虚拟根目录。所产生的效果是 Cookie 只能用于 Application1 文件夹或虚拟根目录中的页面。例如,如果您的站点名称为 www.contoso.com,则在前面示例中创建的 Cookie 将只能用于路径为 http://www.contoso.com/Application1/ 的页面以及该文件夹下的所有页面。但是,Cookie 将不能用于其他应用程序中的页面,如 http://www.contoso.com/Application2/ 或 http://www.contoso.com/ 中的页面。

  说明:在某些浏览器中,路径区分大小写。您无法控制用户如何在其浏览器中键入 URL,但如果应用程序依赖于与特定路径相关的 Cookie,请确保您创建的所有超链接中的 URL 与 Path 属性值的大小写相匹配。

  默认情况下,Cookie 与特定域关联。例如,如果您的站点是 www.contoso.com,那么当用户向该站点请求任何页时,您编写的 Cookie 就会被发送到服务器。

4、读取 Cookie

  在 ASP.NET 应用程序中,可以使用 HttpRequest 对象读取 Cookie,该对象可用作 Page 类的 Request 属性使用。HttpRequest 对象的结构与 HttpResponse 对象的结构基本相同,因此,可以从 HttpRequest 对象中读取 Cookie,并且读取方式与将 Cookie 写入 HttpResponse 对象的方式基本相同。下面的代码示例演示两种方法,通过这两种方法可获取名为 username 的 Cookie 的值,并将其值显示在 Label 控件中:

//读取单个Cookie中的值
//法1:
if(Request.Cookies["userName"] != null)
    Label1.Text = Request.Cookies["userName"].Value;
//法2:
if(Request.Cookies["userName"] != null)
{
    HttpCookie aCookie = Request.Cookies["userName"];
    Label1.Text = Server.HtmlEncode(aCookie.Value);
}
//读取带有子健的Cookie的值
if(Request.Cookies["userInfo"] != null)
{
    Label1.Text = Request.Cookies["userInfo"]["userName"];

    Label2.Text =Request.Cookies["userInfo"]["PWD"];
}
读取Cookie

  注意:在尝试获取 Cookie 的值之前,应确保该 Cookie 是否存在;如果该 Cookie 不存在,将会收到 NullReferenceException 异常。

5、修改和删除 Cookie

  由于 Cookie 在用户的计算机中,因此无法将其直接修改/移除。但是,可以让浏览器来为您删除 Cookie。不能直接修改 Cookie。更改 Cookie 的过程涉及创建一个具有新值的新 Cookie,然后将其发送到浏览器来覆盖客户端上的旧版本 Cookie。该技术是创建一个与要删除的 Cookie 同名的新 Cookie,并将该 Cookie 的到期日期设置为早于当前日期的某个日期。当浏览器检查 Cookie 的到期日期时,浏览器便会丢弃这个现已过期的 Cookie。修改/删除Cookie跟编写Cookie是一样的,就是编写新的同名的Cookie。

//修改Cookie的值的过程与创建Cookie的过程相同
 HttpCookie cookie = new HttpCookie("User");
cookie.Values["UserName"] = "Jack";
cookie.Values["PWD"] = "123";
cookie.Expires = DateTime.Now.AddDays(1);
cookie.HttpOnly = true;
Response.AppendCookie(cookie);

//删除Cookie,创建一个与要删除的 Cookie 同名的新 Cookie,并将该 Cookie 的到期日期设置为早于当前日期的某个日期。
HttpCookie cookie = new HttpCookie("User");
cookie.Expires = DateTime.Now.AddDays(-10);
Response.AppendCookie(cookie);

//删除应用程序中所有可用 Cookie
HttpCookie Cookie;
string cookieName;
int limit = Request.Cookies.Count;
for (int i=0; i<limit; i++)
{
    cookieName = Request.Cookies[i].Name;
    Cookie= new HttpCookie(cookieName);
    Cookie.Expires = DateTime.Now.AddDays(-1);
    Response.Cookies.Add(Cookie);
}
修改和删除Cookie

  修改单个子键的方法与创建它的方法相同。若要删除单个子键,可以操作 Cookie 的 Values 集合,该集合用于保存子键。首先通过从 Cookies 对象中获取 Cookie 来重新创建 Cookie。然后您就可以调用 Values 集合的 Remove 方法,将要删除的子键的名称传递给 Remove 方法。接着,将 Cookie 添加到 Cookies 集合,这样 Cookie 便会以修改后的格式发送回浏览器。下面的代码示例演示如何删除子键。在此示例中,要移除的子键的名称在变量中指定。

string subkeyName;
subkeyName = "PWD";
HttpCookie aCookie = Request.Cookies["userInfo"];
aCookie.Values.Remove(subkeyName);
aCookie.Expires = DateTime.Now.AddDays(1);
Response.Cookies.Add(aCookie);
删除Cookie子健

6、Cookie 和安全性

  Cookie 的安全性问题与从客户端获取数据的安全性问题类似。在应用程序中,Cookie 是另一种形式的用户输入,因此很容易被他们非法获取和利用。由于 Cookie 保存在用户自己的计算机上,因此,用户至少能看到您存储在 Cookie 中的数据。用户还可以在浏览器向您发送 Cookie 之前更改该 Cookie。

  千万不要在 Cookie 中存储敏感信息,如用户名、密码、信用卡号等等。不要在 Cookie 中放置任何不应由用户掌握的内容,也不要放可能被其他窃取 Cookie 的人控制的内容。

  同样,不要轻信从 Cookie 中得到的信息。不要假定数据与您写出时相同;处理 Cookie 值时采用的安全措施应该与处理网页中用户键入的数据时采用的安全措施相同。

  Cookie 以明文形式在浏览器和服务器间发送,任何可以截获 Web 通信的人都可以读取 Cookie。可以设置 Cookie 属性,使 Cookie 只能在使用安全套接字层 (SSL) 的连接上传输。SSL 并不能防止保存在用户计算机上的 Cookie 被读取或操作,但可防止 Cookie 在传输过程中被读取,因为 Cookie 已被加密。

7、确定浏览器是否接受 Cookie

  用户可将其浏览器设置为拒绝接受 Cookie。在不能写入 Cookie 时不会引发任何错误。同样,浏览器也不向服务器发送有关其当前 Cookie 设置的任何信息。

  Cookies 属性不指示 Cookie 是否启用。确定 Cookie 是否被接受的一种方法是尝试编写一个 Cookie,然后再尝试读取该 Cookie。如果无法读取您编写的 Cookie,则可以假定浏览器不接受 Cookie。

8、Cookie 和会话状态

  当用户导航到您的站点时,服务器为该用户建立唯一的会话,会话将一直延续到用户访问结束。ASP.NET 会为每个会话维护会话状态信息,应用程序可在会话状态信息中存储用户特定信息。有关更多信息,请参见 ASP.NET 会话状态概述主题。 

  ASP.NET 必须跟踪每个用户的会话 ID,以便可以将用户映射到服务器上的会话状态信息。默认情况下,ASP.NET 使用非永久性 Cookie 来存储会话状态。但是,如果用户已在浏览器上禁用 Cookie,会话状态信息便无法存储在 Cookie 中。

  ASP.NET 提供了无 Cookie 会话作为替代。可以将应用程序配置为不将会话 ID 存储在 Cookie 中,而存储在站点中页面的 URL 中。如果应用程序依赖于会话状态,可以考虑将其配置为使用无 Cookie 会话。但是在较少的情况下,如果用户与他人共享 URL(可能是用户将 URL 发送给同事,而该用户的会话仍然处于活动状态),则最终这两个用户可能共享同一个会话,结果将难以预料。有关将应用程序配置为使用无 Cookie 会话的更多信息,请参见 ASP.NET 状态管理概述主题。 

posted @ 2020-07-17 15:56  墨染暖栀  阅读(772)  评论(0编辑  收藏  举报
/* 看板娘 */ /* 粒子吸附*/