隨著 Web
應用程序的出現,直接在客戶端存儲用戶信息的需求也隨之出現。這背后的想法是合理的:與特定用戶相關的信息應該保存在用戶的機器上。無論是登錄信息、個人偏好,還是其他數據,Web
應用程序提供者都需要有辦法把它們保存在客戶端。對該問題的第一個解決方案就是 cookie
。
cookie
cookie
是 HTTP
請求標頭,其中含有先前由服務器通過 set-cookie
標頭投放或通過 Javascript
的 Document.cookie
方法設置,然后存儲到客戶端的 HTTP cookie
。例如下面是包含這個頭部的一個 HTTP
響應:
HTTP/1.1 200 ok
Content-type: text/html
Set-Cookie: name=value
這個 HTTP
響應會設置一個名為 name
,值為 value
的 cookie
。名和值在發送時都會經過 URL
編碼。瀏覽器乎存儲這些會話信息,并在之后的每個請求中都會通過 HTTP
頭部 cookie
再將它們分會服務器,比如:
GET /index.js HTTP/1.1
Cookie: name=value
這些發送會服務器的額外信息可用于唯一標識發送請求的客戶端。
為什么 HTTP 需要 cookie
HTTP
是一種無狀態的協議,這意味著服務器無法在連續的請求之間保持客戶端的任何記憶。
接下來我們就來舉一個生活的例子:
假設你假設去一家麥當勞,他們提供了一個優惠活動,就是買滿 2 杯可樂可以送一只炸雞。
你進入這家店店了一杯可樂,收銀員會將你的點單信息輸入他們的系統中。如果沒有 cookie
的話,這服務員在你下次來的時候,壓根就不知道你是新客還是之前就已經點過了;
服務器為你分配一個唯一的會話標識符,并將其存儲在一個名為 session_id
的 cookie
中。這個 cookie
會存儲在你的瀏覽器中;
在你買完付款后,服務器會將一些與你的購買相關的信息存儲在 cookie
中,如購買的可樂數量和金額;
在你繼續購買咖啡的過程中,服務器會在每個請求中檢查你的 session_id
cookie
,并根據其中存儲的購買信息來判斷是否滿足送咖啡的條件;
當你購買的可樂數量達到 2 杯時,服務器會識別出你已經滿足了送炸雞的條件。它會在你的購買信息中添加一條記錄,表示你可以獲得一只免費的炸雞;
當你下次訪問咖啡店并購買咖啡時,服務器會讀取你的 cookie
中的購買信息,并在檢查后繼續更新送咖啡的記錄;
當你結賬時,服務器會檢查購買信息中的送咖啡記錄,如果滿足條件,會從賬單中減去相應的金額,表示免費咖啡的抵扣;
通過使用 cookie
,麥當勞的服務器可以跟蹤你的購買數量,并根據設定的條件來提供送炸雞的優惠。這樣,當你購買滿足要求的數量時,服務器可以自動判斷并為你提供一杯免費的咖啡,使你在購買咖啡時能夠享受到優惠和獎勵。
cookie 的限制
cookie
是與特定域綁定的,設置 cookie
后,它會與請求一起發送到創建它的域,這個限制能保證 cookie
中存儲的信息只對被認可的接收者開發,不被其他域訪問。
因為 cookie
存儲在客戶端機器上,所以為保證它不會被惡意利用,瀏覽器會施加限制,同時 cookie
也不會占用太多磁盤空間。
通常,只要遵守以下大致的限制,就不會在任何瀏覽器中碰到問題:
容量限制: 每個 cookie
的存儲容量通常被限制在幾個 kb
到幾十 kb
之間,不同瀏覽器可能會有不同的限制,如果超過了這個限制,瀏覽器可能會拒絕保存 cookie
或將其截斷;
數量限制: 瀏覽器對每個域名或整個瀏覽器的 cookie
數量也有限制,如果超過了這個數量限制,舊的 cookie
可能會被覆蓋或丟棄;
安全限制: 瀏覽器實施了一些安全策略來限制 cookie
的使用,例如它使用 HttpOnly
屬性來來防止通過 Javascript
訪問 cookie
,從而減少了被跨站腳本攻擊(Cross-site-scripting,XSS
) 對 cookie
的信息竊取。同樣使用 Secure
屬性用于限制僅在 HTTPS
安全連接時,才可以發送 Cookie
;
域名和路徑限制: cookie
可以設置域名和路徑限制,指定了可以接收該 cookie
的域名范圍和 URL
路徑。這樣 cookie
只能在指定的域名和路徑下被發送和接收。例如,如果將 cookie
的域名限制為 .example.com
,則只有以 example.com
結尾的子域名可以接受該 cookie
;
需要注意的是,不同的瀏覽器和設備可能存在差異,對 cookie
的限制和實施策略可能會有所不同。此外,隨著隱私和安全意識的提高,相關的法規和標準也可能對 cookie
的使用提出更嚴格的要求。因此,在開發和使用 cookie
時,需要遵守相關的法規和最佳實踐,以確保用戶隱私和數據安全。
cookie 的構成
一個標準的 HTTP
cookie
通常由以下幾個組成部分構成:
名稱(name
): cookie
的名稱通常用于標識和引用該 cookie
;
值(value
): cookie
的值是否于名稱相關聯的信息,它可以是任意文本或數據;
域(Domain
): cookie
的域定義了可以訪問該 cookie
的域名范圍,只有與該域匹配的網站才能讀取發送該 cookie
;
路徑(Path
): 路徑規定了可以訪問該 cookie
的 URL
路徑,只有與指定匹配的頁面才能訪問該 cookie
;
過期時間(Expiration
): cookie
的過期時間指定了該 cookie
的有效期限。一旦超過了過期時間,瀏覽器將刪除該 cookie
。如果沒有指定過期時間,那么該 cookie
將成為會話 cookie
,只在當前會話期間有效,即關閉瀏覽器后將被刪除;
安全標志(Secure
):如果設置了安全標志為 true
,那么瀏覽器只會在通過加密的安全連接 HTTPS
發送該 cookie
。這可以增加 cookie
的安全性,防止在傳輸過程中被竊取或篡改;
HTTPOnly
標志: 如果設置了 HTTPOnly
標志為 true
,那么該 cookie
將不允許通過客戶端的 Javascript
代碼訪問。這有助于減少跨站腳本攻擊 XSS
對 cookie
的利用;
這些組成部分以鍵值對的形式存儲在 cookie
中,并由瀏覽器在 HTTP
請求和響應中進行傳輸。這些標志用于告訴瀏覽器什么情況下應該在請求中包含 cookie
,這些參數并不會隨請求發送個服務器,實際發送的只有 cookie
的 鍵/值 對。
cookie 的缺點
盡管 HTTP
cookie
是廣泛使用的機制,但它也存在一些缺點:
隱私問題: Cookie
可以用于跟蹤用戶的行為和偏好,這引發了隱私方面的擔憂。第三方 cookie
可以在不同的網站之間共享和跟蹤用戶信息,可能導致用戶的隱私泄露和個人數據被濫用的風險;
安全風險: 由于 cookie
存儲在用戶的瀏覽器中,攻擊者可能會通過各種手段竊取 cookie
,如 網絡嗅探
、跨站腳本攻擊 XSS
和跨站請求偽造 CSRF
等。一旦攻擊者獲取了 cookie
,他們可能會模擬用戶的身份,并訪問敏感信息或執行未經授權的操作;
性能影響: 每個 HTTP
請求中都會包含所有與當前域相關的 cookie
信息,這會增加數據傳輸的大小,對于每個 HTTP
請求,瀏覽器都需要將 cookie
信息發送給服務器,這會增加網絡流量和延遲,特別是當 cookie
的數量或大小較大時;
容量限制: 每個 cookie
的存儲容量是有限的,通常在幾 KB
到幾十 KB
之間。對于需要存儲大量數據的應用程序,cookie
的容量限制可能會成為問題;
跨域限制: 瀏覽器實施了一些安全策略,限制了對其他域名的 cookie
訪問,跨域請求(跨域 ajax 請求
)不能訪問其他域的 cookie
,這對于某些應用程序可能會帶來限制;
用戶控制性不足: 盡管瀏覽器提供了一些控制 cookie
的選項,如禁用第三方 cookie
或使用 隱身模式,但用戶對于如何管理和控制 cookie
的細粒度控制有限;
鑒于這些缺點,對于保護用戶隱私和數據安全的考慮,開發人員和網站運營者應該謹慎使用 cookie
,并遵循隱私和安全最佳實踐,以確保合理使用和保護用戶的個人信息。
總結
為了合理使用 Cookie
并保護用戶隱私,開發人員應遵循隱私和安全最佳實踐,限制 Cookie
的使用,并提供用戶對 Cookie
的控制選項。用戶也可以通過瀏覽器設置來管理和刪除 Cookie
,以控制其數據的使用和共享。
不要在 cookie
中存儲重要或敏感的信息,cookie
數據不是保存在安全的環境中,因此任何人都可能獲得,應該避免把信用卡號或個人地址等信息保存在 cookie
中。
原文鏈接
該文章在 2023/6/26 14:40:09 編輯過