Session Management

Vibe Prompt

「幫我實作安全的 Session 管理:HTTP-only、Secure、SameSite Cookie,Session 儲存在 Redis。」

安全 Cookie 設定

// Express
app.use(session({
  store: new RedisStore({ client: redisClient }),
  secret: process.env.SESSION_SECRET,
  resave: false,
  saveUninitialized: false,
  cookie: {
    httpOnly: true,      // JavaScript 無法讀取
    secure: true,        // 僅 HTTPS
    sameSite: 'strict',  // 防止 CSRF
    maxAge: 24 * 60 * 60 * 1000, // 24 小時
  },
}));

Redis Session Store

import Redis from 'ioredis';
import session from 'express-session';
import RedisStore from 'connect-redis';

const redis = new Redis({
  host: process.env.REDIS_HOST,
  port: 6379,
  password: process.env.REDIS_PASSWORD,
});

app.use(session({
  store: new RedisStore({ client: redis }),
  secret: process.env.SESSION_SECRET,
  cookie: {
    httpOnly: true,
    secure: true,
    sameSite: 'strict',
    maxAge: 86400000,
  },
}));

Session Fixation 防護

// 登入後重新生成 Session ID
app.post('/login', async (req, res) => {
  const user = await authenticate(req.body);
  if (user) {
    req.session.regenerate((err) => {
      req.session.userId = user.id;
      res.json({ success: true });
    });
  }
});

關鍵要點

  • ✅ 請根據本章主題補充具體的學習重點
  • ✅ 建議加入比較表格、程式碼範例或流程圖
  • ✅ 確保內容扎實且有價值

Session 攻擊與防禦

Session Hijacking(劫持)

攻擊者竊取使用者的 Session ID 來冒充身分。

| 攻擊方式 | 說明 | 防禦措施 | |---------|------|---------| | 側錄網路封包 | 在公共 WiFi 監聽 HTTP 流量 | 強制 HTTPS + HSTS | | XSS 偷取 Cookie | 透過 XSS 讀取 document.cookie | HttpOnly + Secure Cookie | | Session 固定 | 讓使用者使用攻擊者指定的 Session ID | 登入後重新產生 Session ID | | 暴力猜測 | 猜測弱 Session ID | 使用高熵值的亂數 |

Session 安全設定

// Express.js Session 設定
app.use(session({
  name: "__Host-session",  // 前綴確保 Cookie 安全
  secret: process.env.SESSION_SECRET,
  resave: false,
  saveUninitialized: false,
  cookie: {
    httpOnly: true,      // 禁止 JavaScript 讀取
    secure: true,        // 僅透過 HTTPS 傳送
    sameSite: "lax",     // CSRF 防護
    maxAge: 7 * 24 * 60 * 60 * 1000,  // 7 天
  }
}));

JWT vs Session

| 比較 | JWT (Stateless) | Session (Stateful) | |------|:---------------:|:------------------:| | 儲存位置 | 客戶端 Cookie | 伺服器端資料庫/Redis | | 可撤銷性 | ❌ 發出後無法撤銷 | ✅ 立即刪除 Session | | 擴展性 | ✅ 不需要共享儲存 | ⚠️ 需要共用 Session 儲存 | | 安全性 | 需注意 JWT 簽章 | Session ID 是亂數更安全 |



Session 管理的核心:JWT vs Session

很多開發者會問:「到底要用 JWT 還是 Session?」

答案是:看你的需求。

| 比較 | JWT (無狀態) | Session (有狀態) | |:----:|:-----------:|:---------------:| | 儲存位置 | 客戶端 Cookie | 伺服器端(Redis / 資料庫) | | 可撤銷性 | ❌ 發出後無法單方面撤銷 | ✅ 立即刪除 Session 即可 | | 擴展性 | ✅ 不需要共享儲存 | ⚠️ 需要共用 Redis/DB | | 安全性基礎 | 簽章演算法(需保護密鑰) | Session ID 是亂數,更安全 | | 大小 | 較大(包含 Payload) | 極小(只是一個亂數 ID) | | 適合場景 | API 授權、微服務、跨站認證 | 傳統網頁應用、需要立即撤銷權限 |

常見的 Session 攻擊

| 攻擊 | 手法 | 防禦 | |:----:|:----:|:----:| | Session Hijacking | 竊取 Session Cookie | HttpOnly + Secure + SameSite | | Session Fixation | 讓使用者使用攻擊者指定的 Session ID | 登入後重新產生 Session ID | | 暴力猜測 | 嘗試猜測 Session ID | 使用高熵值的亂數 ID | | XSS | 透過 XSS 讀取 Cookie | HttpOnly Cookie | | CSRF | 利用已登入的 Session 執行惡意操作 | SameSite Cookie + CSRF Token |

下一章預告:從 Session 到 PKCE

Session 和 JWT 都是傳統的認證方式。但對於 SPA(單頁應用)和手機 App,有更好的選擇——PKCE (Proof Key for Code Exchange)

下一章將深入 OAuth 2.0 的 PKCE 流程,這是你開發現代化 App 和 SPA 時必須掌握的認證技術。

解鎖完整教學內容

本章為付費內容。加入專案即可解鎖超過 5000 字的深度解析,包含 10 個以上神級 Prompt 與真實 Source Code 範例!