ASP.NET中Cookie编程的基础知识(6)
删除 Cookie删除 Cookie(即把该 Cookie 从用户的硬盘上物理删除)是修改 Cookie 的一种形式。由于 Cookie 位于用户的计算机中,所以您无法直接将其删除。但是,您可以让浏览器为您删除 Cookie。修改 Cookie 的方法前面已经介绍过(即用相同的名称创建一个新的 Cookie),不同的是将其有效期设置为过去的某个日期。当浏览器检查 Cookie 的有效期时,就会删除这个已过期的 Cookie。
所以,删除 Cookie 的方法与创建该 Cookie 的方法是相同的,只不过要把其有效期设置为过去的某个日期。以下示例比删除单个 Cookie 要稍微有趣一些,它使用的方法可以删除当前域的所有 Cookie:
Dim i As Integer
Dim cookieName As String
Dim limit As Integer = Request.Cookies.Count - 1
For i = 0 To limit
aCookie = Request.Cookies(i)
aCookie.Expires = DateTime.Now.AddDays(-1)
Response.Cookies.Add(aCookie)
Next修改或删除子键
修改单个子键的方法与最初创建它的方法相同:
Response.Cookies("userInfo")("lastVisit") = DateTime.Now.ToString
Response.Cookies("userInfo").Expires = DateTime.Now.AddDays(1)比较复杂的问题是如何删除单个子键。您不能只是简单地重新设置 Cookie 的过期日期,因为这样只能删除整个 Cookie 而不能删除单个子键。实际的解决方案是对包含子键的 Cookie 的 Values 集合进行操作。首先,通过从 Request.Cookies 对象中获取 Cookie 来重新创建 Cookie。然后,您就可以调用 Values 集合的 Remove 方法,将要删除的子键名称传递到 Remove 方法。接下来,您通常可以将修改后的 Cookie 添加到 Response.Cookies 集合,以便将修改后的 Cookie 发送回浏览器。
以下代码显示了如何删除子键。在示例中,要删除的子键的名称在变量中指定。
Dim subkeyName As String
subkeyName = "userName"
Dim aCookie As HttpCookie = Request.Cookies("userInfo")
aCookie.Values.Remove(subkeyName)
aCookie.Expires = DateTime.Now.AddDays(1)
Response.Cookies.Add(aCookie)Cookie 与安全性
在使用 Cookie 时,您必须意识到其固有的安全弱点。我所指的安全性并不是隐私问题,正如我在前面的什么是 Cookie?中所述,隐私在更大程度上是某些用户面对的问题:这些用户很关心 Cookie 中的信息是如何被使用的。而 Cookie 的安全性问题与从客户机获取数据的安全性问题类似。对于初学者,就应用程序而言,Cookie 是用户输入的另一种形式,因而很容易被他人非法获取和利用。由于 Cookie 保存在用户自己的计算机上,所以用户至少可以看到您保存在 Cookie 中的信息。如果用户愿意,还能在浏览器向您发送 Cookie 之前修改该 Cookie。
所以,您千万不要在 Cookie 中保存保密信息 - 用户名、密码、信用卡号等等。在 Cookie 中不要保存不应该由用户掌握的内容,也不要保存可能被其他窃取 Cookie 的人控制的内容。
同样,要对从 Cookie 中得到的任何信息都持怀疑态度。不要认为得到的数据就是您当初设想的信息。处理 Cookie 值时采用的安全措施应该与处理 Web 页面中用户键入的数据时采用的安全措施相同。例如,在页面中显示值之前,我会对 Cookie 中的内容进行 HTML 编码。这是一种标准的方法,可以在显示之前净化从用户处得到的信息,对 Cookie 的处理与此相同。
另一个需要关心的问题是,Cookie 是以纯文本的形式在浏览器和服务器之间传送的,任何可以截取 Web 通信的人都可以读取 Cookie。您可以对 Cookie 的属性进行设置,使其只能在使用安易做图接字层(SSL,又称 https://)的连接上传输。SSL 并不能防止保存在用户计算机上的 Cookie 被他人读取或操作,但它能防止 Cookie 在传输途中被他人截取。本文不讨论 SSL,但您必须清楚,您可以对 Cookie 进行传输保护。有关 SSL 的详细信息,请参阅 Secure Sockets Layer: Protect Your E-Commerce Web Site with SSL and Digital Certificates(英文)。
面对这些安全问题,如何才能安全地使用 Cookie?您可以在 Cookie 中保存一些不重要的数据,如用户首选项或其他对应用程序没有重大影响的信息。如果确实需要把某些敏感信息(如用户 ID)保存在 Cookie 中,就对这些信息进行加密。一种可行的方法是利用 ASP.NET Forms Authentication 实用程序创建一个身份验证票据,作为 Cookie 保存。本文不讨论有关加密的问题,但是,如果您需要在 Cookie 中保存敏感信息,就应该试着采取措施来隐藏信息,防止被他人盗用。
在 Mitigating Cross-site Scripting With HTTP-only Cookies(英文)一文中,您可以了解到更多有关 Cookie 及其安全弱点的信息。
检查浏览器是否接受 Cookie
我在前面的 Cookie 的限制一节中曾经提到一个潜在问题,即用户可以设置自己的浏览器拒绝接受 Cookie。如何才能知道您是否可以读写 Cookie?在不能写入 Cookie 时不会出现任何错误(例如 Response.Cookies 不会抛出异常),因为服务器并不跟踪呈现页面后出现的情况。浏览器同样不会向服务器发送任何有关其当前的 Cookie 设置的信息。(也许您需要了解,但 HttpBrowserCapabilities.Cookies Property [英文] 属性并不会告诉您 Cookie 是否被启用,而只能告诉您当前的浏览器是否支持 Cookie。)
一种确定浏览器是否接受 Cookie 的方法是先编写一个 Cookie,然后再尝试读取这个 Cookie。如果不能读取这个 Cookie,则可以认为该浏览器不接受 Cookie。
我编写了一个简单的示例来说明如何测试 Cookie 是否被接受。该示例包含两个页面。在第一个页面中,我编写了一个 Cookie,然后把浏览器重新定向到第二个页面。第二个页面尝试读取这个 Cookie,转而将浏览器重新定向到第一个页面,并向 URL 添加一个带有测试结果的查询字符串变量。
第一个页面的代码如下:
Sub Page_Load()
If Not Page.IsPostBack Then
If Request.QueryString("AcceptsCookies") Is Nothing Then
Response.Cookies("TestCookie").Value = "ok"
Response.Cookies("TestCookie").Expires = _
DateTime.Now.AddMinutes(1)
Response.Redirect("TestForCookies.aspx?redirect=" & _
Server.UrlEncode(Request.Url.ToString))
Else
labelAcceptsCookies.Text = "接受 Cookie = " & _
Request.QueryString("AcceptsCookies")
End If
End If
End Sub第一个页面测试是否有回信,如果没有,就搜索包含测试结果的查询字符串变量 (AcceptsCookies)。如果没有找到查询字符串变量,则表示测试还没有完成,代码就写出一个名为“TestCookie”的 Cookie。写出 Cookie 之后,示例调用 Response.Redirect 来切换到测试页面 (TestForCookies.aspx)。附加到测试页面的 URL 的是名为 redirect 的查询字符串变量,该变量中包含了当前页面的 URL,这样就能在执行测试后把重定向到该页面。
测试页面可以完全由代码组成,不需要包含控件。以下就是我使用的代码:
Sub Page_Load()
Dim redirect As String = Request.QueryString("redirect")
Dim acceptsCookies As String
是否接受 Cookie?
If Request.Cookies("TestCookie") Is Nothing Then
没有 Cookie,因此不需要接受
acceptsCookies = 0
Else
acceptsCookies = 1
删除测试 Cookie
Response.Cookies("TestCookie").Expires = _
DateTime.Now.AddDays(-1)
End If
Response.Redirect(redirect & "?AcceptsCookies=" & acceptsCookies, _
True)
End Sub
读取 redirect 查询字符串变量后,代码就尝试读取 Cookie。为了实现日常管理,如果该 Cookie 确实存在,就会被立即删除。测试完成后,代码从 redirect 查询字符串变量传递的 URL 构造一个新的 URL。新的 URL 也包括一个包含测试结果的查询字符串变量。最后一步是使用新的 URL 将浏览器重定向到原来的页面。
这个示例十分简单,但说明了通过运行程序并查看结果来进行测试的基本原则。其中最需要改进的地方是要永久保存 Cookie 测试结果,这样用户就不必在每次浏览原始页面时都重复进行测试。但是,实际上并不能做到这一点。Cookie 不会起作用,原因是显而易见的。另一种可能是把测试结果保存在会话状态中,但在默认情况下,会话状态也依赖于 Cookie,而如果浏览器不接受 Cookie,会话状态也不会起作用。解决后一个问题的办法是采用无 Cookie 的会话状态。下一节我将简要介绍会话状态如何与 Cookie 协作。
Cookie 和会话状态
当用户访问您的站点时,服务器会为该用户创建唯一的会话,会话将一直延续到用户访问结束。对于每个会话,ASP.NET 都维护一种基于服务器的结构(会话状态),在该结构中应用程序可以保存用户的相关信息。有关详细信息,请参阅 Session State(英文)。
ASP.NET 需要能跟踪每个用户的会话 ID,这样才能把用户映射到服务器上的会话状态信息。默认情况下,ASP.NET 使用一个非永久性的 Cookie 来保存会话状态。如果您使用读取 Cookie 一节的“读取 Cookie 集合”中的示例,您可能就会在 Cookie 中发现一个会话状态 Cookie。
但是如果用户禁用了浏览器的 Cookie,会话状态就不能使用 Cookie 来保存会话 ID,会话状态也不会起作用。这就是为什么我在前面的检查浏览器是否接受 Cookie 中说,无法在 Cookie 测试完毕后把测试结果实际保存在会话状态中,因为没有 Cookie 就没有会话状态。
ASP.NET 提
补充:Web开发 , ASP.Net ,