萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 網路程式設計 >> PHP 程式設計

PHP Session 工作原理深度解析:生命週期、儲存機制、分散式 Session、安全配置

Session 運作流程

  1. session_start():讀取 Cookie PHPSESSID,或產生新 ID
  2. 根據 Session ID 從儲存介質(檔案/Redis/DB)載入資料到 $_SESSION
  3. 腳本結束時,自動序列化 $_SESSION 寫回儲存介質
  4. 關閉瀏覽器 → Cookie 失效(Session Cookie),但伺服器端資料保留至 gc

儲存處理器

處理器設定優點缺點
files (預設)session.save_handler=files零設定、預設啟用單機、大量檔案效能差、難水平擴展
Redissession.save_handler=redis
session.save_path="tcp://127.0.0.1:6379"
高效能、原生支援集群、TTL 自動過期需額外元件
Memcachedsession.save_handler=memcached
session.save_path="127.0.0.1:11211"
記憶體級速度、分散式資料不可靠(重啟遺失)、無原生 TTL 掃描
Database自訂 session_set_save_handler持久化、可查詢、ACID寫入延遲、需維護 schema

分散式 Session 方案

方案一:Redis 集中儲存(推薦)

# php.ini
session.save_handler = redis
session.save_path = "tcp://redis-cluster:6379?auth=password&database=0&prefix=PHPSESS:"
session.gc_maxlifetime = 1440

方案二:資料庫自訂處理器

class DbSessionHandler implements SessionHandlerInterface {
    private PDO $pdo;
    public function __construct(PDO $pdo) { $this->pdo = $pdo; }
    public function open($path, $name): bool { return true; }
    public function close(): bool { return true; }
    public function read($id): string|false {
        $stmt = $this->pdo->prepare('SELECT data FROM sessions WHERE id = ? AND expiry > ?');
        $stmt->execute([$id, time()]);
        return $stmt->fetchColumn() ?: '';
    }
    public function write($id, $data): bool {
        $expiry = time() + ini_get('session.gc_maxlifetime');
        $stmt = $this->pdo->prepare('INSERT INTO sessions (id, data, expiry) VALUES (?, ?, ?)
            ON DUPLICATE KEY UPDATE data=VALUES(data), expiry=VALUES(expiry)');
        return $stmt->execute([$id, $data, $expiry]);
    }
    public function destroy($id): bool {
        $stmt = $this->pdo->prepare('DELETE FROM sessions WHERE id = ?');
        return $stmt->execute([$id]);
    }
    public function gc($maxlifetime): int|false {
        $stmt = $this->pdo->prepare('DELETE FROM sessions WHERE expiry < ?');
        $stmt->execute([time()]);
        return $stmt->rowCount();
    }
}

// 註冊
$handler = new DbSessionHandler($pdo);
session_set_save_handler($handler, true);
session_start();

安全配置清單

<?php
// 必須在 session_start() 之前設定
ini_set('session.cookie_httponly', '1');      // 防 XSS 竊取
ini_set('session.cookie_secure', '1');        // 僅 HTTPS 傳送
ini_set('session.cookie_samesite', 'Lax');    // CSRF 防護
ini_set('session.use_strict_mode', '1');      // 拒絕未初始化的 Session ID
ini_set('session.sid_length', '48');          // ID 長度(PHP 7.1+)
ini_set('session.sid_bits_per_character', '6'); // 熵值
ini_set('session.gc_probability', '1');
ini_set('session.gc_divisor', '1000');        // 0.1% 機率觸發 GC
ini_set('session.gc_maxlifetime', '1440');    // 24 分鐘

session_start();

Session 固定攻擊防禦

<?php
session_start();

// 登入成功後,重新產生 ID
if ($loginSuccess) {
    session_regenerate_id(true); // true = 刪除舊 session 檔案
    $_SESSION['user_id'] = $userId;
}

常見函式速查

函式用途
session_start()啟動/恢復 Session
session_id()取得/設定當前 ID
session_name()取得/設定 Cookie 名稱(預設 PHPSESSID)
session_regenerate_id()產生新 ID,可選刪除舊資料
session_destroy()銷毀伺服器端資料(不刪除 Cookie)
session_unset()清空 $_SESSION 陣列
session_write_close()提前寫入並關閉,釋放鎖定
session_set_save_handler()註冊自訂儲存介面

原始來源:www.111cn.net

copyright © 萬盛學電腦網 all rights reserved