程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> ASP.NET中Cookie編程的基礎知識(6)

ASP.NET中Cookie編程的基礎知識(6)

編輯:關於.NET
刪除 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 提供了一種解決方案,即利用無 Cookie 的會話。您可以配置自己的應用程序,不在 CookIE 中保存會話 ID,而是在站點頁面的 URL 中保存。會話 ID 保存在 URL 中,也就是 ASP.Net 將 ID 保存在浏覽器中,從而能夠在用戶請求其他頁面時取回 ID。

  無 CookIE 會話可以避免浏覽器拒絕 Cookie 的問題,使您能夠使用會話狀態。如果您的應用程序依賴於會話狀態,您可能就需要對其進行配置,使它能使用無 CookIE 會話。但是,在某些情況下,如果用戶與其他人共享 URL - 可能是用戶通過電子郵件將 URL 發送給同事,而該用戶的會話仍然處於激活狀態 - 那麼最終這兩個用戶可能共享同一個會話,結果將難以預料。
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved