Web Storage: HTTP, Cookie, Session 1


Posted by urlun0404 on 2022-05-06

昨天面試被問到cookie的意思,前幾天有看到當場卻答不出來有點糗哈,留一篇來釐清一下觀念。篇幅允許的話順便記錄local storage、session storage和剛剛看到的token XD

(註:以下以HTTP Cookie為例說明。)


HTTP

在認識Cookie以前先複習網路和HTTP協定。這邊先問兩個問題「當使用者點擊網站頁面的時候發生了什麼事?」,以及「HTTP在瀏覽器發送請求、從伺服器取得回應的訊息(或資訊)傳輸過程扮演什麼角色?」

第一個問題是:「當使用者點擊網站頁面的時候發生了什麼事?

為了簡化這篇文章的內容,以下用非常簡單的案例來說明:

首先,使用者透過瀏覽器(Browser)進入某個購物網站,恰好在網站首頁就看到自己可能想購買的商品,於是使用者點擊這個商品的連結按鈕,向購物網站發送請求(Request),這個請求就是「我點擊了這個商品的連結,請給我這個商品的介紹頁面」,而後購物網站的伺服器(Server)會根據使用者請求,找到這個頁面回傳(Response)給使用者。

第二個問題是:「HTTP在瀏覽器發送請求、從伺服器取得回應的訊息(或資訊)傳輸過程扮演什麼角色?

HTTP全名是超文字傳輸協定,所謂超文字一般是指可在電腦或電子裝置上被瀏覽的文字,例如網頁。協定就有點像是為了方便溝通的約定或規範,譬如人與人之間想要快速且向對方傳達最正確的訊息,最有效的方式就是兩個人都使用同一種語言來溝通,而不是在沒透過翻譯軟體、比手畫腳的方式下,你講英文、我講中文;如果另一個人也想來聊天,結果他卻用日文,想當然這個聊天內容會顯得有些混亂。

或者說今天手機只剩30%電力又剛好不小心忘記帶自己的 type C 充電線,結果朋友們都用水果手機、只有lightning 傳輸線,這種情況下就會覺得手機充電孔的 規格沒統一 好像有那麼一點不便?

因此在任何人都可以使用網路、在網路上傳播訊息的狀況下,勢必需要一些準則來確保大家都是在同一種規範底下傳播訊息,而HTTP就是制定網路上傳輸內容的共同規範。


Cookie

然而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

一樣,以下摘錄自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來達成。

另外,Cookie可依其生命週期分為 Session cookiePermenant cookie,並且要注意如果是使用Cookie來辨識已授權使用者,使用者離開並重返網站時應該要重新發送新的Session cookie以避免session fixation attacks

從資訊安全面向來看,使用Cookie時可以多增加一些屬性,有關Cookie的屬性設定可參考MDN文件,以下是幾個MDN有介紹到的屬性:

  1. Secure:表示伺服器只接收經由HTTPS協定所傳送的加密請求(Encrypted request)
  2. HttpOnly:設定此屬性值的 Cookie 不能被 JavaScript的 Document.cookie方法操作。
  3. Domain:設定Cookie可發送的Host,且設定後表示Cookie可送到此Domain和其Subdomain;要注意的是設定Domain屬性的Cookie不會考慮請求(request)的來源。
  4. Path:發送Cookie的網址主目錄須為指定的Path和其他子目錄
  5. SameSite:主要是判斷請求的Cookie來源是否為_同源_。
    • 所謂的來源(Origin)是指 scheme (protocol)hostname (domain)port of the URL
    • SameSite 屬性值包含 StrictLaxNone;通常是用來避免跨域攻擊(CSRF)

最後是MDN有提到說過去常使用Cookie儲存資訊在Client-side,但Cookie會跟著每個請求一併送出而造成不好的效能;所以現在建議改用Web Storage API或者IndexedDB API儲存資料。

結果這篇太長,其他名詞只好下一篇繼續Orz


後記
重新理解後發現以前學的網路概念除了TCP/IP和Packet,其他都忘的差不多了,而且有些概念看起來是跟作業系統比較有關係,需要找時間補網路和作業系統。

另外SameSite屬性值的設定和Cookie資安問題感覺可以拉出來另外寫兩篇,有機會再來研究研究。


References


#Network #web storage #HTTP #cookie #session







Related Posts

git author 設定

git author 設定

CSS單位大全 (px,em,rem,vh,vw,vmin,vmax)

CSS單位大全 (px,em,rem,vh,vw,vmin,vmax)

LeetCode 1. Two Sum

LeetCode 1. Two Sum


Comments