看似簡單,實則考察對 Session 機制、GC 隨機性、Cookie 與 Session 差異、分布式存儲的深度理解。
ini_set('session.gc_maxlifetime', 1800); // 30分鐘
致命缺陷:
mtime 為準,若用戶 5 分鐘前活躍,文件 mtime 更新,實際存活 35 分鐘/tmp,最小 gc_maxlifetime 會誤刪其他應用 Sessionini_set('session.cookie_lifetime', 1800);
致命缺陷:
// Redis 自動過期,精確到毫秒
ini_set('session.save_handler', 'redis');
ini_set('session.save_path', 'tcp://127.0.0.1:6379?auth=pass');
// Session 寫入時自動 EXPIRE 1800
優勢:
<?php
// 1. 啟動 Session(放在所有輸出前)
session_start();
// 2. 設置 Cookie 參數(同步客戶端預期)
$lifetime = 1800; // 30分鐘
session_set_cookie_params($lifetime, '/', '', true, true); // Secure + HttpOnly
// 3. 每次請求檢查服務端時間戳
if (isset($_SESSION['_last_activity'])) {
$idle = time() - $_SESSION['_last_activity'];
if ($idle > $lifetime) {
// 嚴格過期:銷毀 Session
session_unset();
session_destroy();
session_start(); // 重新生成新 Session ID
session_regenerate_id(true);
}
}
// 4. 更新最後活躍時間
$_SESSION['_last_activity'] = time();
// 5. 可選:定期清理舊 Session 文件(配合 Cron)
// find /var/lib/php/sessions -type f -cmin +30 -delete
session_regenerate_id(true) 刪除舊 Session 文件| 追問 | 核心回答要點 |
|---|---|
| 為什麼不用 gc_maxlifetime? | 概率觸發、mtime 延遲、共享目錄污染 |
| 如何解決分布式 Session 共享? | Redis/Memcached + 統一 save_handler |
| Session 劫持如何防範? | HttpOnly、Secure、SameSite、定期 Regenerate ID、綁定 UA/IP 指紋 |
| 如何實現「記住我」長期登錄? | 獨立 Remember Token 表,Token 加密存儲 Cookie,驗證後自動登錄並重置 Session |
| Session 與 JWT 區別? | Session 有狀態/服務端存儲/可撤銷;JWT 無狀態/客戶端攜帶/不可撤銷(除非黑名單) |