瀏覽器 HttpOnly Cookie圖

使用HttpOnly Cookie,Token 不會被 JS 讀取?

有朋友看到這篇「 你知道 Cookie、LocalStorage、SessionStorage 的使用時機嗎? 」內容,對於

Token 不被 JS 存取,這件事情感到疑惑

正常來說,JavaScript 在瀏覽器上的行為”大部分”都是可以操作的,但是根據 MDN,在瀏覽器裡,「JavaScript 不被存取」通常指的就是把 Token 放在一個 帶有 HttpOnly 屬性的 Cookie 內。帶有這個屬性的 Cookie,瀏覽器在收到響應時會儲存它、並在每次發請求時自動附加,但JavaScript 卻永遠無法透過 document.cookie 讀取到它。這正是「Token 不被 JS 存取」的典型情境。

  1. 防範 XSS 攻擊 如果 Token(或 Session ID)存在於 localStoragesessionStorage 或一般 Cookie,任何注入到頁面的惡意腳本都可能透過 JavaScript 把它「讀」出來,再送給攻擊者;而 HttpOnly Cookie 一旦設置,JS 就完全無法碰它,大幅提高了對抗 XSS 的能力。
  2. 自動送出請求 帶有 HttpOnly(通常還會加上 Secure、SameSite)屬性的 Cookie,瀏覽器每次發同網域請求時都會自動夾帶,前端無需在程式裡手動把它放到 Authorization header。

典型範例:Laravel Sanctum 的 SPA 模式

  • 後端 在使用者登入成功後,透過 Set-Cookie: XSRF-TOKEN=…; HttpOnly; Secure; SameSite=Strict 發送一個 HttpOnly Cookie。
  • 前端 只要在 axios/fetch 中設定 withCredentials: true,瀏覽器就會自動把這個 Cookie 附帶在後續所有 API 請求裡。
  • JavaScript 完全無法讀取或篡改這個 Cookie,Token 保存在瀏覽器、卻對前端程式碼「隱身」。

就存取行為來討論,你想把後端做成 Stateless API,但又想沿用瀏覽器的 Cookie 機制(例如使用 Laravel Sanctum),或是當你最在意 XSS 風險,且不需要讓前端程式動態讀取 Token。

這時候就適合選用 HttpOnly Cookie

取捨、比較

儲存方式JS 是否可讀取安全性使用場景
localStorage客製化操作(如前端自行插 header)
一般 Cookie兼顧傳統 Session 或輕量追蹤
HttpOnly Cookie高(防 XSS)高安全性認證(如金鑰、Session ID、JWT)
  • 優點:防 XSS、瀏覽器代為傳送
  • 缺點:無法由前端動態讀取、無法自己決定何時夾帶(必須用 cookie-based API)

回到「Token 不被 JS 存取」

這句話正是在描述「把認證 Token 存成 HttpOnly Cookie 的做法」,也就是:瀏覽器替你管理、JS 永遠拿不到,卻能在每次 API 呼叫時自動帶上,以達到更安全的認證流程。

實作步驟

  1. 後端回應時設定 Set-Cookie: <你的 Token>=…; HttpOnly; Secure; SameSite=Strict
  2. 前端請求時帶上 withCredentials: true
  3. 後端驗證 Cookie 中的 Token,即完成安全的認證策略