Session

Last updated: Apr 3, 2026

以下是 Session 的完整運作流程與實作細節:


1. 運作流程 (Workflow)

Session 的實作通常遵循以下四個步驟:

  1. 登入驗證:使用者提交帳密,伺服器驗證正確。
  2. 建立 Session
  • 伺服器在後端生成一個唯一的 Session ID(通常是長度隨機且不可預測的字串)。
  • 伺服器將使用者的資訊(如 user_id, role)存入儲存媒介(如記憶體、Redis 或資料庫),並與該 ID 綁定。
  1. 發送 Cookie:伺服器透過 HTTP Header Set-Cookie 將 Session ID 傳給瀏覽器。
  2. 後續請求:瀏覽器之後發送請求時,會自動帶上這個 Cookie。伺服器拿到 ID 後去後端比對,確認是誰在操作。

2. 儲存媒介的選擇

實作時,Session 存放在哪裡至關重要:

  • Memory (內存):最簡單(如 Express-session 預設),但伺服器重啟資料會消失,且無法跨伺服器共享。
  • Redis / Memcached (推薦):最主流做法。速度極快,且支援設定 TTL (過期時間),適合分散式系統。
  • Database (資料庫):最穩,但頻繁讀寫會對資料庫造成壓力。

3. 安全性的關鍵設定

實作 Session 時,Cookie 的設定是防禦攻擊的重中之重:

設定參數 說明 防禦的攻擊
HttpOnly 務必開啟。讓 JavaScript 無法讀取 Cookie。 XSS (跨站腳本攻擊)
Secure 規定 Cookie 只能在 HTTPS 連線下傳輸。 中間人攻擊 (攔截封包)
SameSite 設定為 LaxStrict。限制跨站請求攜帶 Cookie。 CSRF (跨站請求偽造)
Max-Age / Expires 設定 Session 的有效期,避免永久有效。 降低設備遺失的風險

4. 程式碼範例 (Node.js + Express)

這是一個標準的實作範例,展示了如何配置安全的 Session:

const session = require('express-session');
const RedisStore = require('connect-redis')(session);
const { createClient } = require('redis');

// 1. 初始化 Redis 用於儲存 Session
let redisClient = createClient({ legacyMode: true });
redisClient.connect();

app.use(session({
  store: new RedisStore({ client: redisClient }), // 儲存在 Redis
  secret: 'your_super_secret_key',              // 用來加密 Cookie 的金鑰
  resave: false,                                // 若 Session 無變動不重新存儲
  saveUninitialized: false,                     // 不要為未登入者建立空白 Session
  cookie: {
    httpOnly: true,                             // 防止 JS 讀取
    secure: true,                               // 僅限 HTTPS (正式環境開啟)
    sameSite: 'lax',                            // 防禦 CSRF
    maxAge: 1000 * 60 * 30                      // 30 分鐘後過期
  }
}));

// 2. 登入成功後存入資料
app.post('/login', (req, res) => {
  // 假設驗證成功
  req.session.userId = 'user_123'; 
  res.send('Logged in!');
});


5. 缺點與挑戰

雖然 Session 安全且易控,但在實作時需注意:

  1. 水平擴展 (Scaling):如果你有兩台伺服器,必須確保它們都能讀到同一個 Redis,否則 Load Balancer 把使用者導向 A 機,B 機卻沒資料。
  2. CSRF 防禦:Session 極度依賴 Cookie,因此除了 SameSite 設定外,通常還需要額外的 CSRF Token 機制。

你想瞭解如何在分散式架構(例如多台伺服器)中具體設定 Redis 來管理 Session,還是想看看如何針對這個機制進行 CSRF 的防範測試?