ASP.NET之Cookie

艾碼士J發表於2020-07-25
1.Cookie概述

1.1.學習心得

  本文不可能將cookie每個細節講的面面俱到,學習亦是。本人覺得學習Cookie主要在於兩大方面,一方面是運用二是安全方面,而不是一上來就死記硬背它的那些特點。運用方面需要實操演練cookie的細節特性,也就是本文中的Cookie的關鍵項組成”章節中的五個屬性並且要做到通過DEMO實際去驗證該屬性的一些特點,在深入領悟了其中的道理和相關的涉及面就可以很好的運用cookie;安全方面這塊涉及到很多網路知識,我覺得作為程式設計師學習可以基本瞭解下,等到專案中緊密涉及到在進行深入,不然該方面會橫向擴充涉及很多知識面,考慮到時間成本上並不划算。

 

1.2.簡介Cookie

  我理解最簡單的一句話概括:一種可以用於客戶端與伺服器之間傳輸的資料儲存功能,從而實現WEB的狀態保持和會話跟蹤。

   並且該資料最終會以文字檔案存放在客戶端上,並且每個cookie儲存資料量不能超過4KB。

   在資料儲存方面,cookie儲存的是明文資料並且客戶端是具備一些修改cookie的能力,所以不建議將敏感的資料存放在cookie中。

 

1.3存在的價值

   和很多其他的儲存WEB狀態的物件一樣,由於HTTP是一個無狀態的協議,簡單來比喻說:伺服器中的WEB頁面是沒有記憶的,他記不住你來過還是第一次來,所以它需要藉助一些類似儲存性質的手段來實現記憶,當你來過時(狀態),避免下次在來的時候做一些重複的工作(保持狀態)。這一特性是每個WEB狀態物件都具備的,然而在根據每個狀態物件的細節特性可以運用實現不同的功能,如Cookie可以運用到“記住使用者名稱”、“單點登入”等場景中。

 

1.4.Cookie之廣告說

  我們每個人可能都會經歷如下一種場景,例如你在百度搜尋了一些你感興趣的東西(如手機)來了解一些詳情資料,然後當你在去登入淘寶貨京東之類的電商網站時他就會自動給你推送你曾經在百度上搜尋的一些商品廣告。這塊的技術實現就使用到了Cookie,電商網站會根據在訪問百度瀏覽時儲存的cookie資料從而跟每個不同的人推送感興趣的商品。


 2.Cookie在客戶端和伺服器之間的互動

 以一個記住使用者名稱的一個運用場景繪製一個客戶端瀏覽器和伺服器的互動圖:

 在這個互動的過程中我們要記住以下:

1.關於報文

cookie的資料在傳輸過程中都放在在報文頭中,當伺服器建立cookie響應給瀏覽器時,cookie的內容是在響應報文的請求頭中並在Set-Cooke屬性中,這裡還要強調一點是如果存在多個Cookie響應,那麼Set-Cookie就存在多個;並且瀏覽器只要請求伺服器就會將於伺服器有關聯的Cookie資料放在請求報文的請求頭中,傳送給伺服器。

2.關於儲存

Cookie執行的儲存操作是一種物理形式,該操作是瀏覽器來完成的,伺服器中建立的cookie只是組織資料告知瀏覽器來實際的執行。


3.Cookie的關鍵項組成

 3.1.Name/Value屬性

 Cookie儲存和讀取資料都是以鍵值對的形式進行操作的,例如:Request.Cookies[“uid”]=”bob”;

 Name即是鍵Value則是指。在儲存資料時大多數瀏覽器對資料有大小的限制都在4KB以內,如果出現相同的鍵則後儲存的會將上一個覆蓋。

 

3.2.Expires屬性

 用於設定Cookie的到期時間,超過該時間cookie會失效。

 根據該屬性的設定與否,將cookie分為了兩種性質:

   第一種是會話性cookie,即沒有設定該屬性時,cookie的資料是儲存在客戶端的記憶體中,並且當使用者關閉瀏覽器時cookie就失效。顧名思義,就像一段電話一樣,電話打完了相關的語音即刻就斷掉。

   第二種是永續性cookie,即設定了該屬性cookie有了指定失效的時間,此時的cookie的資料是儲存在電腦的硬碟上,當到了失效時間或者使用者手動通過瀏覽器清除時cookie在會失效。

   Cookie的刪除其實就是通過將該屬性設定為一個已經過期的時間,從而瀏覽器會對cookie進行清除。

 

 3.3.Path屬性

  用於設定某個Cookie允許訪問的目錄,例如你只想讓此Cookie讓網站下某個指定目錄下內碼表面進行訪問,就可以設定該屬性。預設的情況下也就是沒有指定此屬性時,設定的Cookie在對應的站點中所有頁面均可訪問。

   這裡還有一個細節需要注意,如果設定指定目錄才能訪問,那麼瀏覽器在傳送請求時除了指定目錄會傳送cookie,其他的頁面瀏覽器不會傳送cookie請求報文頭中也不會存在cookie的資料。

實操驗證:

 示例說明:

  通過請求Test.ahsx頁面建立一個cookie並設定了指定允許訪問的目錄A,頁面請求後瀏覽器接收到伺服器返回的cookie在響應報文頭中,接下來分別請求A目錄和B目錄的兩個頁面,由於cookie只允許A目錄的頁面才能訪問,所以在請求A.ahsx頁面時成功的輸出了cookie中的資料,並觀察到只有在請求A目錄的頁面時瀏覽器的請求報文中才會有cookie資料。

   另外,通過設定該屬性可以縮小訪問的範圍從而提高一定的安全性。

 

3.4.Domain屬性

   指定了可以訪問該Cookie的域名,預設值是當前站點所在伺服器的域。

   簡單來說cookie的訪問不能跨域例如,www.baidu.com站點建立的cookie在www.sina.com站點中是不能訪問的。

   但是不能跨域不代表不能跨伺服器或站點,因為域名可以指向多臺伺服器或多個不同的網站系統,因為cookie機制並未嚴格遵守同源策略,例如www.baidu.com:801站點建立的cookie可以在www.baidu.com:802站點中進行讀取,然而此特性對於實現單點登入非常有用。

 下圖示例兩個不同的站點共享cookie資料,因為兩個站點都在同域下。


 另外這裡還補充一點:

  上述說cookie不能跨域名訪問,並且不能跨瀏覽器訪問不同瀏覽器設定的cookie都是不相關的,例如你在谷歌瀏覽器在部落格園上進行了登入,部落格園使用cookie記錄你的使用者名稱,然後你在IE瀏覽器訪問部落格園此時IE不能獲取你在谷歌瀏覽記住的使用者名稱,需要重新輸入。

 

 3.4.Secure屬性

   指定是否使用HTTTPS安全協議傳送Cookie。使用HTTP安全協議,可以保護Cookie在瀏覽器和Web伺服器之間傳輸過程中不被竊取和篡改。個人覺得Domain屬性的特性在一定範圍上擴充了Cookie的使用範圍但是會造成一定的安全隱患,最簡單的方式就是將站點部署為HTTPS的站點併為Cookie設定該屬性。

 

3.5HTTPOnly屬性

   用於防止客戶端通過JS指令碼document.cookie屬性訪問cookie,有助於保護Cookie不被跨站指令碼攻擊竊取或篡改。但是,HTTPOnly的應用仍存在侷限性,一些瀏覽器可以被阻止使JS讀取cookie,但允許寫的操作;此外大多數瀏覽器仍允許通過XMLHTTP物件讀取HTTP響應中的Set-Cookie頭從而獲取cookie資料,個人覺得該屬性的存在沒有太大的實際意義。


 4.在ASP.NET中使用Cookie

 使用Cookie很簡單,也根本不用記住,還是秉承著“要什麼點什麼”的原則就行,如:Request.Cookies。

下面還是官方的寫下程式碼:

 1   HttpCookie cookieUid = Request.Cookies["uid"];
 2 
 3             if (cookieUid==null) //第一次訪問,則建立
 4             {
 5                 cookieUid = new HttpCookie("uid", Request["uid"]);
 6                 cookieUid.Expires = DateTime.Now.AddDays(1);
 7             }
 8             else  // 非第一次,則直接讀取
 9             {
10                 string uid = cookieUid.Value;
11                 Response.Write("當前登入使用者名稱:"+uid);
12             }

 在寫程式碼時需要注意:

  1. ASP.NET在程式碼組織中將Cookie分為兩種,一種是客戶端請求的,另一種是伺服器響應的,也就是:Request.Cookies和Response.Cookie。在向瀏覽器傳送Cookie時,不要將Response.Cookie寫成Request.Cookies,否則會導致cookie建立失敗。
  2. 在寫Cookie一定要考慮設定有效期,如果沒有設定那麼該cookie的有效期,那這就屬於一個會話性Cookie,在瀏覽器關閉時Cookie就會銷燬。

 

相關文章