接續前一篇的HTTP,HTTP規範有一些小小的問題,以下摘錄自MDN:
HTTP is a stateless protocol, meaning that the server does not keep any data (state) between two requests.
意思是HTTP本身不會保留傳遞的訊息,或者更精確地說 不會記錄狀態(stateless) ,這種性質可能會造成一些麻煩。
例如使用者進入購物網站挑選商品,購物網站在理想上應該要於使用者切換頁面尋找商品的時候,必須儲存使用者目前已經放在購物車的商品。然而因為HTTP不會保留所傳達的資訊,伺服器會視每一次瀏覽器發送的請求都是獨立、不相關的,意即使用者每切換一次頁面,購物車的商品就會不見 ── 因為按照HTTP的規範「切換頁面」等於「不同使用者在切換頁面」,所以伺服器會提供一個新的、空的購物車給 另一位使用者 。
不過瀏覽器背後實質上都是同一位使用者在操作欸?
為了解決這個問題,必須讓遵守HTTP協定溝通的購物網站伺服器 辨識出這是同一位使用者 ,並且 保存 已放入購物車的商品資訊,而能用來幫忙保存使用者和購物車商品這類資訊的 其中一項工具 就是 cookie。
Cookie
一樣,以下摘錄自MDN文件:
An HTTP cookie (web cookie, browser cookie) is a small piece of data that a server sends to a user's web browser. The browser may store the cookie and send it back to the same server with later requests.
白話一點的說:
Typically, an HTTP cookie is used to tell if two requests come from the same browser—keeping a user logged in, for example.
換言之,Cookie就是伺服器回應瀏覽器時夾帶在HTTP Response Header的一種資訊儲存媒介,是一個最大可以儲存4kb資訊的小型文字檔。
這個媒介會由伺服器傳給一開始向它發送請求的瀏覽器,之後同一個瀏覽器發送請求時,只要這個瀏覽器發送的HTTP請求Header有相同的Cookie,就會被伺服器視為這是同一個瀏覽器所發送的請求。
所以,任何需要伺服器記住是同一個人(browser)在做的事情,例如登入、購物車、個人化設定,甚至追蹤和分析使用者的行為,都能使用cookie來達成。
Types of Cookies
另外,cookie可依其生命週期分為 Session cookie 和 Permenant cookie,並且要注意如果是使用Cookie來辨識已授權使用者,使用者離開並重返網站時應該要重新發送新的Session cookie以避免session fixation attacks
從資訊安全面向來看,使用cookie時可以多增加一些屬性,有關cookie的屬性設定可參考MDN文件,以下是幾個MDN有介紹到的屬性:
Secure
:表示伺服器只接收經由HTTPS協定所傳送的加密請求(Encrypted request)HttpOnly
:設定此屬性值的cookie不能被 JavaScript的Document.cookie
方法操作。Domain
:設定cookie可發送的Host,且設定後表示cookie可送到此Domain和其Subdomain;要注意的是設定Domain
屬性的cookie不會考慮請求(request)的來源。Path
:發送cookie的網址主目錄須為指定的Path
和其他子目錄SameSite
:主要是判斷請求的cookie來源是否為_同源_。- 所謂的來源(Origin)是指 scheme (protocol) 、 hostname (domain) 和 port of the URL 。
SameSite
屬性值包含Strict
、Lax
、None
;通常是用來避免跨域攻擊(CSRF)。
最後是MDN有提到說過去常使用cookie儲存資訊在client-side,但Cookie會跟著每個請求一併送出而造成不好的效能;所以現在建議改用Web Storage API或者IndexedDB API儲存資料。
Cookie vs Session
回頭來看cookie和session的差別,session代表某種短暫狀態的一段時期,cookie其實只是儲存session訊息的其中一種媒介。
我們常說cookie儲存session ID,表示這個cookie儲存了某位用戶端與伺服器端所建立的某個session,session ID就是用來指明儲存的是 哪個Session ,而伺服器端就是仰賴這個session ID來 辨識 它是否還正在和同一個用戶連線。一旦session結束,就會銷毀跟這段時期有關的所有一切;如果用戶端重新和伺服器端建立另一個session,會是跟前一次獨立、不相干的session。
如果前一篇還是有點深奧,Stackoverflow的這則回答用了比較實際的例子說明,或許會更容易理解cookie和session的差別,因為這則回答更加明確地說cookie只是用來儲存資訊的媒介,也有其他像是URL參數這種儲存資料的方法。
後記
重新理解後發現以前學的網路概念除了TCP/IP和Packet,其他都忘的差不多了,而且有些概念看起來是跟作業系統比較有關係,需要找時間補網路和作業系統。
另外SameSite
屬性值的設定和Cookie資安問題感覺可以拉出來另外寫兩篇,有機會再來研究研究。
References
- Using HTTP cookies @MDN
- Cookie @Computer Hope
- Difference between Session and Cookies @GeeksforGeeks
- RFC 6265
- Origin @MDN
- Same-origin policy @MDN
- What are the security differences between cookies with Domain vs SameSite strict? @stackoverflow
- SameSite cookies explained @Julien Cretel's blog
- The great SameSite confusion
- Document.cookie @MDN
- Difference between Local Storage, Session Storage, and Cookies in JavaScript
- How cookies can track you (Simply Explained)