PHP Cookie 工作原理深度解析:從協議層到實戰應用
Cookie 是 HTTP 無狀態協議中維持會話狀態的核心機制。理解其底層運作原理、安全屬性、跨域行為與 PHP 具體 API,對構建安全可靠的 Web 應用至關重要。
HTTP 協議層面運作流程
- 伺服器設定:回應頭包含
Set-Cookie: name=value; attributes
- 瀏覽器儲存:依域名/路徑/安全屬性儲存於本地 Cookie 罐
- 後續請求:瀏覽器自動在請求頭附上
Cookie: name=value(符合條件時)
- 伺服器讀取:PHP 解析
$_COOKIE 超全域變數
# 實際 HTTP 交互範例
HTTP/1.1 200 OK
Set-Cookie: session_id=abc123; Path=/; Domain=example.com; Secure; HttpOnly; SameSite=Lax; Max-Age=3600
Content-Type: text/html
GET /dashboard HTTP/1.1
Host: example.com
Cookie: session_id=abc123
PHP setcookie() 完整參數詳解
bool setcookie(
string $name, // Cookie 名稱
string $value = "", // 值(自動 urlencode)
int $expires = 0, // 過期 Unix 時間戳,0=瀏覽器關閉失效
string $path = "", // 生效路徑,預設當前目錄
string $domain = "", // 生效域名,預設當前主機
bool $secure = false, // 僅 HTTPS 傳輸
bool $httponly = false // 禁止 JavaScript 存取 (防 XSS)
);
// PHP 7.3+ 支援陣列選項語法
setcookie('name', 'value', [
'expires' => time() + 3600,
'path' => '/',
'domain' => '.example.com',
'secure' => true,
'httponly' => true,
'samesite' => 'Lax', // None|Lax|Strict
]);
關鍵屬性安全影響分析
| 屬性 | 功能 | 安全建議 |
| Secure | 僅 HTTPS 傳輸 | 生產環境必須啟用,防止中間人竊聽 |
| HttpOnly | 阻止 JS document.cookie 存取 | 所有認證 Cookie 必須啟用,緩解 XSS 影響 |
| SameSite | 跨站請求攜帶策略 | Lax 平衡安全與體驗;Strict 最高安全;None 需配合 Secure 用於跨域 |
| Domain | 生效域名範圍 | 避免設定過寬(如 .com),子域共享用 .example.com |
| Path | 生效路徑前綴 | 預設 / 即可,過窄路徑易造成混淆 |
| Expires/Max-Age | 存活時間 | Session Cookie 用 0;持久 Cookie 設定合理過期(如 30 天) |
PHP 實戰操作範例
1. 設定安全 Session Cookie
// php.ini 全域配置(推薦)
session.cookie_secure = 1
session.cookie_httponly = 1
session.cookie_samesite = "Lax"
session.use_strict_mode = 1
session.cookie_lifetime = 0
// 或運行時設定(需在 session_start() 前)
ini_set('session.cookie_secure', '1');
ini_set('session.cookie_httponly', '1');
ini_set('session.cookie_samesite', 'Lax');
session_start();
2. 自定義業務 Cookie
// 設定:用戶偏好,30 天有效,全站可用
setcookie('user_theme', 'dark', [
'expires' => time() + 86400 * 30,
'path' => '/',
'domain' => '.example.com', // 子域共享
'secure' => true,
'httponly' => true, // 純後端使用
'samesite' => 'Lax',
]);
// 讀取
$theme = $_COOKIE['user_theme'] ?? 'light';
// 刪除(設定過去時間)
setcookie('user_theme', '', [
'expires' => time() - 3600,
'path' => '/',
'domain' => '.example.com',
'secure' => true,
'httponly' => true,
]);
3. Cookie 陣列結構化存儲
// 設定陣列(實際為多個同名不同下標 Cookie)
setcookie('prefs[theme]', 'dark', $options);
setcookie('prefs[lang]', 'zh-TW', $options);
setcookie('prefs[font_size]', '16', $options);
// 讀取(PHP 自動解析為陣列)
$prefs = $_COOKIE['prefs'] ?? [];
// ['theme' => 'dark', 'lang' => 'zh-TW', 'font_size' => '16']
進階主題
1. 子域共享 Cookie 架構
// 主域 example.com 設定登入 Cookie
setcookie('auth_token', $token, [
'expires' => time() + 3600,
'path' => '/',
'domain' => '.example.com', // 關鍵:前綴點號
'secure' => true,
'httponly' => true,
'samesite' => 'Lax',
]);
// 子域 api.example.com、app.example.com 自動攜帶
// 需確保所有子域 HTTPS、同屬一級域
2. SameSite 屬性深度解析
| 值 | 行為 | 適用場景 |
| Strict | 僅第一方請求攜帶(連結跳轉不帶) | 高安全操作(轉帳、刪除資料) |
| Lax | 第一方 + 安全跨站導航(GET 連結) | 大多數認證 Cookie 推薦預設 |
| None | 所有跨站請求攜帶(需 Secure) | 跨域 API、嵌入式 Widget、SSO |
3. Cookie 與 Session 差異對比
| 維度 | Cookie | Session |
| 儲存位置 | 客戶端瀏覽器 | 伺服器(檔案/Redis/DB) |
| 容量限制 | 單個 4KB,總計 ~300 個/域 | 受伺服器記憶體/磁碟限制 |
| 安全性 | 可被竄改、竊取、攔截 | 資料不離開伺服器,相對安全 |
| 生命週期 | 可設定持久化 | 通常瀏覽器關閉失效,可配置持久 |
| 跨域行為 | 受 SameSite/Domain 控制 | 需共享 Session 儲存介質 |
| 典型用途 | 偏好設定、追蹤、Remember Me | 用戶認證狀態、購物車、敏感資料 |
常見漏洞與防護
- Session Fixation:登入後重新生成 Session ID
session_regenerate_id(true)
- Cookie 注入:值經
urlencode(),但路徑/域名參數需驗證
- CSRF 攻擊:SameSite=Lax + CSRF Token 雙重防護
- 子域洩露:
.example.com 會暴露給所有子域,敏感 Cookie 限制具體子域
- 超大 Cookie 影響效能:每請求攜帶,控制在 1KB 以內
現代替代方案
- LocalStorage/SessionStorage:純客戶端儲存,不隨請求自動發送,適合非敏感大量資料
- IndexedDB:結構化客戶端資料庫
- JWT (JSON Web Token):無狀態認證,攜帶於 Authorization Header,避免 Cookie CSRF 風險
- HttpOnly Cookie + CSRF Token:傳統表單應用最佳組合
掌握 Cookie 協議細節與 PHP API 正確用法,配合 SameSite、HttpOnly、Secure 三大安全屬性,能有效防範會話劫持、CSRF、XSS 等常見攻擊,構建可信賴的用戶認證體系。