cover

概念概覽

flowchart TD
    Data["前後端資料儲存機制"] --> Client["客戶端儲存"]
    Data --> Server["伺服器端儲存"]
    Data --> Token["Token 機制"]

    Client --> Cookie["Cookie<br/>~4KB / 自動傳送"]
    Client --> LS["LocalStorage<br/>~5MB / 永久"]
    Client --> SS["SessionStorage<br/>~5MB / 分頁關閉清除"]

    Server --> Session["Session<br/>儲存在伺服器<br/>透過 Cookie 識別"]

    Token --> JWT["JWT Token<br/>自包含憑證<br/>無狀態"]

    style Data fill:#f96,stroke:#333,stroke-width:2px
    style Client fill:#bfb,stroke:#333
    style Server fill:#bbf,stroke:#333
    style Token fill:#fbf,stroke:#333

資料儲存方式比較

特性CookieLocalStorageSessionStorageSessionToken
儲存位置瀏覽器瀏覽器瀏覽器伺服器瀏覽器
容量限制~4KB~5MB~5MB無限制~8KB
生命週期可設定永久分頁關閉可設定可設定
自動傳送✅(via Cookie)
跨域存取同源同源同源伺服器控制無限制

基本概念

Cookie 是伺服器發送給瀏覽器的小型資料,瀏覽器會儲存並在後續請求中自動帶回。

首次請求
瀏覽器                              伺服器
   │ ─── GET /login ────────────→   │
   │ ←── Set-Cookie: session=abc ── │

後續請求(自動帶上 Cookie)
   │ ─── GET /profile ──────────→   │
   │     Cookie: session=abc        │
// 伺服器設定 Cookie
Set-Cookie: token=abc123;
  Path=/;
  Domain=.example.com;
  Expires=Thu, 01 Jan 2025 00:00:00 GMT;
  HttpOnly;
  Secure;
  SameSite=Strict
 
// JavaScript 設定 Cookie(無法設定 HttpOnly)
document.cookie = "theme=dark; path=/; max-age=86400";
屬性說明
HttpOnlyJavaScript 無法存取,防止 XSS
Secure只在 HTTPS 傳送
SameSite防止 CSRF(Strict/Lax/None)
PathCookie 生效路徑
DomainCookie 生效網域
Max-Age/Expires過期時間

Session

基本概念

Session 是存在伺服器端的使用者狀態,透過 Session ID(通常存在 Cookie)識別使用者。

┌─────────────────────────────────────────────────────────┐
│                        伺服器                            │
│  ┌────────────────────────────────────────────────────┐ │
│  │              Session Storage                        │ │
│  │  ┌─────────────────────────────────────────────┐   │ │
│  │  │  "abc123" → { userId: 1, name: "John" }     │   │ │
│  │  │  "def456" → { userId: 2, name: "Jane" }     │   │ │
│  │  └─────────────────────────────────────────────┘   │ │
│  └────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
          ↑
          │ Session ID = "abc123"
          │
    瀏覽器 Cookie
// Cookie-based: 狀態存在客戶端
Set-Cookie: user={"id":1,"name":"John"}  // ❌ 不安全
 
// Session-based: 狀態存在伺服器
Set-Cookie: sessionId=abc123  // ✅ 只傳 ID

Token (JWT)

基本概念

Token 是一個自包含的憑證,包含使用者資訊和簽章,不需要伺服器儲存狀態。

JWT 結構
┌─────────────────────────────────────────────────────────┐
│  Header.Payload.Signature                                │
│                                                          │
│  eyJhbGciOiJIUzI1NiJ9.                     ← Header      │
│  eyJ1c2VySWQiOjEsIm5hbWUiOiJKb2huIn0.      ← Payload     │
│  SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV        ← Signature   │
└─────────────────────────────────────────────────────────┘

Token 使用流程

// 登入後取得 Token
const response = await fetch('/api/login', {
  method: 'POST',
  body: JSON.stringify({ email, password })
});
const { token } = await response.json();
 
// 儲存 Token
localStorage.setItem('token', token);
 
// 後續請求帶上 Token
fetch('/api/profile', {
  headers: {
    'Authorization': `Bearer ${token}`
  }
});

Session vs Token

特性SessionToken (JWT)
狀態儲存伺服器客戶端
擴展性需同步 Session無狀態,易擴展
撤銷機制刪除即失效需黑名單機制
傳輸方式CookieHeader
安全性較高需注意儲存

LocalStorage & SessionStorage

使用方式

// LocalStorage - 永久儲存
localStorage.setItem('theme', 'dark');
localStorage.getItem('theme');  // 'dark'
localStorage.removeItem('theme');
 
// SessionStorage - 分頁關閉就清除
sessionStorage.setItem('tempData', JSON.stringify(data));
sessionStorage.getItem('tempData');

適用場景

儲存方式適用場景
LocalStorage使用者偏好設定、暫存草稿
SessionStorage表單暫存、分頁間不共享的資料
Cookie認證資訊、追蹤用途

安全性考量

XSS 防護

// ❌ 不安全:Token 存 LocalStorage
localStorage.setItem('token', token);
// XSS 攻擊可以輕易竊取
 
// ✅ 較安全:Token 存 HttpOnly Cookie
// JavaScript 無法存取

CSRF 防護

// ✅ 使用 SameSite Cookie
Set-Cookie: session=abc; SameSite=Strict
 
// ✅ 使用 CSRF Token
<form>
  <input type="hidden" name="_csrf" value="random_token">
</form>

實務建議

認證資訊儲存選擇:

安全性優先(推薦)
└─ HttpOnly Cookie + Session
   └─ 伺服器端驗證
   └─ 自動過期
   └─ 防 XSS

可擴展性優先
└─ JWT Token
   └─ 存在 HttpOnly Cookie(推薦)
   └─ 或 Memory + Refresh Token
   └─ 避免存 LocalStorage

一般資料
└─ 需持久化 → LocalStorage
└─ 僅當前分頁 → SessionStorage
└─ 小資料/需自動傳送 → Cookie

延伸閱讀

OWASP Session Management oAuth 相關文件 RESTFul API 前後端分離 - 序章