Cookie
/ COOK-ee /
HTTP 健忘:依設計,伺服器把每則請求都當成從沒見過你一樣對待。但網站需要記住一些事——你已經登入、購物車裡有什麼、你的語言偏好。Cookie 就是讓一個無狀態協定擁有記憶的簡單小把戲。它是一小段文字,由伺服器請你的瀏覽器存起來,並在之後每次向該站台發出的請求中交回去,就像寄物的號碼牌:寄物處記不得你的長相,但你的號碼牌讓他們能再找回你的外套。
這套機制靠兩個標頭。在回應上,伺服器送出「Set-Cookie: sessionId=abc123」。你的瀏覽器把那串字存起來,並標記它來自哪個站台。之後每次向同一站台發出的請求,瀏覽器都會自動附上「Cookie: sessionId=abc123」。伺服器讀到它,便認得這則請求屬於一段持續中的關係。通常 Cookie 並不存你真正的資料;它存的是一個隨機的會話 ID(session ID),伺服器則把實際資料(你的購物車、你的登入狀態)放在自己的資料庫裡,以那個 ID 為索引。如此一來,留在你機器上的秘密只是個無意義的權杖,真正的狀態仍保留在伺服器端。
Cookie 正是把無狀態的網頁變成有狀態應用程式的東西,但它也帶著包袱。正因為瀏覽器會自動送出它們,一個在某站台設下的 Cookie 會悄悄附在向該站台發出的每則請求上——第三方廣告商利用這點跨網站追蹤人們,攻擊者則利用它進行跨站請求偽造(CSRF)。正是這段歷史,使得現代 Cookie 帶有像 Secure(僅走 HTTPS)、HttpOnly(對頁面腳本隱藏)與 SameSite(跨站請求時不送)這類屬性,也是「你接受 Cookie 嗎?」橫幅存在的原因。Cookie 只是被存起來的文字;它是無害還是侵入性的,取決於裡頭裝了什麼、以及誰讀得到它。
你登入了。伺服器回應「Set-Cookie: sessionId=9f2a...」,並在自己的資料庫裡記住 9f2a 屬於你、而且你已通過驗證。從此你載入的每個頁面都會送回「Cookie: sessionId=9f2a...」,於是伺服器不必再問密碼,就能直呼你的名字向你打招呼。
Cookie 攜帶的是一個無意義的會話 ID;真正的狀態存在伺服器的資料庫裡,以那個 ID 為索引。
Cookie 不是程式,無法執行、掃描你的硬碟或夾帶病毒——它只是被存起來的文字。隱私上的疑慮是追蹤,安全上的疑慮是會話 ID 被竊,而不是惡意軟體。