深入解析 Session:從概念到運作方式
更新日期: 2025 年 3 月 4 日
本文為 資安入門 系列文,第 1 篇
- OWASP Top 10:最新的 Web 安全風險與防範措施(2021 版)
- MD5 加密演算法是什麼?
- SHA-1 是什麼?為什麼不再安全?
- 深入解析 Session:從概念到運作方式 👈所在位置
- 什麼是 Session Fixation(會話固定攻擊)?
- HTTP 與 HTTPS 的差別:新手完整指南
- 跨站請求偽造(CSRF)入門指南:攻擊原理、實例與防禦方法
- 跨站指令碼攻擊(XSS)入門指南:從原理到防禦的全解析
- SQL 注入攻擊全解析:從入門到防禦實戰指南
- 新手指南:深入了解 Content-Security-Policy (CSP) 與網站安全
- 從零理解 Same-Origin Policy:瀏覽器安全的第一道防線
- 跨來源資源共享(CORS)完整指南:打破瀏覽器的安全邊界
在現代網頁開發中,使用者與伺服器的互動是一個關鍵問題。HTTP 通訊協議本身是 無狀態(stateless) 的,這意味著每次請求都不會記住先前的資訊。
然而,許多應用程式都需要維持使用者的登入狀態、購物車內容等資訊,這時候 Session(會話) 就派上用場。
本篇文章將從零開始,帶你了解 Session 的概念、用途、運作方式,以及與 Cookie 和 Token 的差異。
HTTP 的無狀態(stateless)特性
當使用者與網站互動時,實際上是客戶端(Client,如瀏覽器、手機應用程式)與伺服器(Server,網站的後端系統)之間互相交換訊息。
這種溝通的方式依賴於HTTP(Hypertext Transfer Protocol,超文本傳輸協議),它負責定義客戶端如何向伺服器發送請求,以及伺服器應如何回應客戶端的請求。
當客戶端向伺服器發送 HTTP 請求(HTTP Request)時,請求的內容可能包含:
- 請求的資源(如
/index.html
,代表請求首頁) - 請求方法(如
GET
表示取得資料,POST
表示提交資料) - 標頭(Headers)(包含瀏覽器資訊、授權資訊、資料類型等)
- 請求主體(Body,視請求類型而定)(用於傳遞表單數據或 API 參數)
伺服器收到請求後,會處理相應的動作,並透過 HTTP 回應(HTTP Response)來返回結果,回應內容可能包含:
- 狀態碼(Status Code)(如
200 OK
表示成功,404 Not Found
表示資源不存在) - 回應標頭(Headers)(包含內容類型、編碼格式等)
- 回應主體(Body)(實際的回應內容,如 HTML 頁面、JSON 資料、圖片等)
然而,HTTP 本身是無狀態(stateless)的協議,這表示每一次 HTTP 請求都是獨立的,伺服器不會記住先前發生的任何互動或資訊。
也就是說,每當客戶端發送新的請求時,伺服器都會將其視為全新的請求,不會自動關聯到使用者之前的任何動作。
換句話說,伺服器不會主動追蹤用戶的訪問狀態,這導致:
- 每次請求都像是「第一次見面」
- 當使用者發送請求時,伺服器無法辨識這個請求是否來自之前已經互動過的使用者。
- 不會記住登入資訊、購物車內容等資料
- 例如,如果你在購物網站加入商品,然後開啟新分頁重新訪問該網站,商品可能會消失,因為伺服器沒有記憶你之前的操作。
- 每次請求都需要重新提供身份驗證資訊(除非使用 Cookie、Session、Token 等技術來維持狀態)
- 例如,每次造訪某個需要登入的頁面,你都需要重新輸入帳號密碼,因為伺服器不記得你已經登入過。
無狀態的請求流程
假設我們有一個簡單的網頁伺服器,使用者發送多個 HTTP 請求,但伺服器不會記住先前的請求。
+--------+ HTTP Request (訪問首頁) +------------+
| Client | -----------------------------> | Server |
+--------+ +------------+
伺服器回應首頁內容
(不記得這位使用者)
+--------+ HTTP Request (點擊產品頁) +------------+
| Client | -----------------------------> | Server |
+--------+ +------------+
伺服器回應產品頁面
(依然不記得這位使用者)
+--------+ HTTP Request (加入購物車) +------------+
| Client | -----------------------------> | Server |
+--------+ +------------+
伺服器處理請求
(但如果沒有 Session 或 Cookie,購物車內容會丟失)
🔺 每次請求都是獨立的,伺服器不會記住之前的請求。
如果 HTTP 具有「狀態」,會怎麼運作?
假設 HTTP 不是無狀態的,而是像「有記憶的服務生」,記住客戶的點單,那麼流程會是這樣:
+--------+ HTTP Request (登入) +------------+
| Client | -----------------------------> | Server |
+--------+ +------------+
伺服器回應「登入成功」
並儲存用戶資訊
+--------+ HTTP Request (點擊產品頁) +------------+
| Client | -----------------------------> | Server |
+--------+ +------------+
伺服器知道這位用戶已登入
可顯示個人化內容
+--------+ HTTP Request (加入購物車) +------------+
| Client | -----------------------------> | Server |
+--------+ +------------+
伺服器記住購物車內容
(不會因為新請求而遺失)
🔺 在有狀態的情況下,伺服器可以記住使用者的資訊,讓體驗更加流暢。
早期如何維持使用者狀態?
在早期網頁應用中,由於 HTTP 是無狀態的,因此開發者需要自行想辦法維持使用者狀態。
Session 的出現取代了部分早期的技術,如下所示:
早期的技術:URL 參數
最早期的方式是將狀態資訊直接附加在 URL 上,例如:
https://example.com/home?user_id=123
缺點:
- 容易暴露敏感資訊
- URL 會變得冗長且難以管理
- 安全性差,容易被修改
Cookie
Cookie 是存儲在用戶瀏覽器中的小型文本文件,開發者可以透過 Cookie 記錄使用者資訊,這在 Session 出現前是主要的狀態管理方式。
缺點:
- 資料存儲在客戶端,安全性較低(可被竄改、盜取)
- 容量有限(一般 4KB 左右)
- 每次請求都會自動傳送 Cookie,可能影響效能
什麼是 Session?
Session(會話) 是伺服器用來追蹤用戶狀態的一種機制。
當使用者連線到網站時,伺服器會為該用戶創建一個唯一的 Session,並在這段期間內儲存與該用戶相關的資訊,例如登入狀態、購物車內容、使用者偏好設定等。
Session 的特點
- 由伺服器端管理,與用戶的請求關聯
- 具有唯一識別碼(Session ID),用來標識每個使用者
- 可儲存較多資訊,適合存放敏感資料
- 會話結束(如關閉瀏覽器、超時)後,Session 可能會自動失效
Session 的運作方式是什麼?
Session 的運作方式主要透過伺服器端儲存+ Session ID 識別,具體步驟如下:
使用者發送請求
當使用者首次造訪網站(如登入),伺服器會:
- 創建一個 Session,並為其分配一個唯一的 Session ID。
- 將該 Session ID 傳送給使用者,通常儲存在 Cookie 中。
用戶後續請求
當使用者再次發送請求時,瀏覽器會自動帶上 Session ID(存於 Cookie 或標頭中),伺服器會根據 Session ID 找回對應的 Session,確認用戶的狀態。
Session 的維持與失效
- Session 可能具有時效性,若使用者長時間未操作,Session 可能會自動過期。
- 手動登出 也會導致 Session 被刪除,使用者需重新登入。
示意圖:
- 用戶登入
客戶端 -> 伺服器: 發送登入請求
伺服器 -> 客戶端: 創建 Session,返回 Session ID (存入 Cookie)
- 用戶請求其他頁面
客戶端 -> 伺服器: 附帶 Session ID,請求其他頁面
伺服器: 根據 Session ID 找回對應資訊,返回結果
- Session 失效
伺服器: 過一段時間後,刪除無效 Session
客戶端: 重新登入以獲取新 Session
Session 與 Cookie 區別。
簡單來說:
- Session ID 存入 Cookie(伺服器端儲存法)
- Cookie 只存一個 Session ID,而所有實際的使用者資訊(如登入狀態、購物車內容)則存放在伺服器端。
- 這樣做的優點是安全性較高,因為重要資訊不會暴露在客戶端,且資料量沒有 Cookie 限制(一般 4KB)。
- 直接存資料在 Cookie(客戶端儲存法)
- 伺服器將完整的使用者資訊直接存入 Cookie,例如:「使用者 ID、購物車內容、登入狀態等」。
- 這樣做的風險是資料容易被修改或竊取,而且 Cookie 本身的容量有限,會影響效能。
圖示說明
Session ID 存在 Cookie(伺服器端存儲)
+--------+ (1) 發送登入請求 +------------+
| Client | -----------------------------> | Server |
| (瀏覽器) | | (網站伺服器) |
+--------+ +------------+
(2) 伺服器建立 Session:
Session ID: XYZ123
使用者 ID: 1001
購物車: 商品A、商品B
儲存於伺服器端
+--------+ (3) 傳回 Session ID +------------+
| Client | <----------------------------- | Server |
+--------+ +------------+
Cookie: SessionID=XYZ123 (只存 ID)
+--------+ (4) 下次請求攜帶 Session ID +------------+
| Client | -----------------------------> | Server |
+--------+ +------------+
(Cookie: SessionID=XYZ123)
(5) 伺服器查找 Session:
找到 XYZ123 → 取得使用者 1001 的資料
返回購物車內容(商品A、商品B)
✅ 優點:
- 安全性高,因為敏感資訊不存於客戶端。
- 容量無限制,伺服器可存放大量資料。
將完整資訊直接存入 Cookie(客戶端存儲)
+--------+ (1) 發送登入請求 +------------+
| Client | -----------------------------> | Server |
+--------+ +------------+
(2) 伺服器回傳完整資訊:
Set-Cookie: user_id=1001; cart=商品A,商品B
+--------+ (3) 瀏覽器存儲 Cookie +------------+
| Client | <----------------------------- | Server |
+--------+ +------------+
Cookie: user_id=1001; cart=商品A,商品B
+--------+ (4) 下次請求攜帶完整資料 +------------+
| Client | -----------------------------> | Server |
+--------+ +------------+
(Cookie: user_id=1001; cart=商品A,商品B)
(5) 伺服器解析 Cookie 取得資訊
**但這些資料可以被客戶端竄改**
❌ 缺點:
- 安全性低,因為所有資料都存在客戶端,可能被修改或盜取。
- 資料容量有限,Cookie 大約 4KB,無法存放過多資訊。
總結
方法 | 存在哪裡 | Cookie 內容 | 安全性 | 容量 |
---|---|---|---|---|
Session ID 存在 Cookie | 伺服器端 | SessionID=XYZ123 | 高 | 無限制 |
直接存資料在 Cookie | 客戶端 | user_id=1001; cart=商品A,商品B | 低(可竄改) | 4KB 限制 |
Session 與 Token 的差別是什麼?
Session 和 Token 都是用來維持使用者身份狀態的技術,但它們的運作方式與適用場景不同。簡單來說:
- Session 是「伺服器端儲存」的機制,伺服器會建立 Session 並存放使用者資訊,客戶端僅保存一個 Session ID。
- Token 是「無狀態(stateless)」的機制,使用者驗證後,伺服器發送一個 Token(如 JWT)給客戶端,之後的請求都帶上這個 Token,伺服器不用存任何狀態。
主要區別
比較項目 | Session | Token(如 JWT) |
---|---|---|
存放位置 | 伺服器 | 客戶端 |
請求時是否需要存取伺服器端資料? | 需要(伺服器要查詢 Session) | 不需要(Token 自帶資訊,伺服器可直接驗證) |
是否有狀態(stateful / stateless) | 有狀態(Stateful),伺服器要記住 Session | 無狀態(Stateless),每次請求都攜帶 Token |
安全性 | 比較高,因為敏感資訊存於伺服器 | 容易被盜用(需要加密和驗證機制) |
適合的應用場景 | 傳統 Web 應用(伺服器端管理狀態) | 前後端分離應用 / API / 行動應用(客戶端自行管理 Token) |
圖示說明
使用 Session(有狀態)
流程:伺服器存取使用者狀態,客戶端只存 Session ID
步驟 1: 使用者登入,伺服器建立 Session,返回 Session ID
+--------+ (1) POST /login +------------+
| Client | -------------------------> | Server |
| (用戶) | 帳號/密碼 | (伺服器) |
+--------+ +------------+
| 創建 Session: |
| ID: XYZ123 |
| UserID: 1001 |
| Role: admin |
+------------+
步驟 2: 客戶端儲存 Session ID(存於 Cookie)
+--------+ (2) Set-Cookie +------------+
| Client | <------------------------ | Server |
+--------+ +------------+
Cookie: SessionID=XYZ123
步驟 3: 之後的請求攜帶 Session ID
+--------+ (3) GET /profile +------------+
| Client | -------------------------> | Server |
+--------+ +------------+
(Cookie: SessionID=XYZ123)
伺服器查詢 Session:
SessionID=XYZ123 → 取得 UserID 1001
返回使用者資訊
✅ 優點:
- 伺服器端管理所有狀態,較難被攻擊者竄改
- 安全性較高,因為資料不會存放在客戶端
❌ 缺點:
- 伺服器需要儲存 Session,大量使用者可能造成效能問題
- 適用於傳統 Web 應用,但不適合 API 或前後端分離架構
使用 Token(無狀態)
流程:伺服器簽發 Token,之後的請求都攜帶 Token,伺服器不存使用者狀態
步驟 1: 使用者登入,伺服器回傳 Token(如 JWT)
+--------+ (1) POST /login +------------+
| Client | -------------------------> | Server |
| (用戶) | 帳號/密碼 | (伺服器) |
+--------+ +------------+
| 產生 Token: |
| "eyJhbGciOi..." |
| (含 UserID、角色等資訊) |
+------------+
步驟 2: 客戶端儲存 Token(存於 LocalStorage 或 Cookie)
+--------+ (2) 回傳 Token +------------+
| Client | <------------------------ | Server |
+--------+ +------------+
Token: "eyJhbGciOi..." (JWT)
步驟 3: 之後的請求攜帶 Token
+--------+ (3) GET /profile +------------+
| Client | -------------------------> | Server |
+--------+ +------------+
(Header: Authorization: Bearer eyJhbGciOi...)
伺服器驗證 Token:
解碼 JWT,取得 UserID 1001
返回使用者資訊
✅ 優點:
- 無狀態(Stateless),伺服器不用存使用者資訊,適合分散式架構
- 適用於 API、行動應用、前後端分離應用
❌ 缺點:
- Token 一旦被盜用,攻擊者可冒充使用者,所以需要額外安全措施(如 Token 期限、簽名驗證)
- Token 無法像 Session 一樣直接「讓使用者登出」,需要在客戶端手動刪除
何時應該用 Session?何時應該用 Token?
使用情境 | 建議使用技術 | 原因 |
---|---|---|
傳統 Web 應用(PHP、Django 等) | Session | 伺服器端管理狀態,安全性高 |
前後端分離的 Web 應用(React、Vue + API) | Token(JWT) | API 無狀態,不需要伺服器存 Session |
行動應用(App + API) | Token(JWT) | 移動裝置不適合 Session,Token 方便跨裝置使用 |
單點登入(SSO) | Token(JWT) | JWT 可以跨服務驗證 |
結論
Session 是伺服器用來管理使用者狀態的關鍵技術,它透過 Session ID 來識別每個使用者,解決了 HTTP 無狀態的問題。
與 Cookie 相比,Session 更安全且適合存儲敏感資訊,而與 Token 相比,Session 需要伺服器維護狀態,適用於傳統的 Web 應用場景。
了解這些技術的區別,能幫助開發者選擇最適合的身份驗證與狀態管理方案。