首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP Session 與 Cookie 實現「記住我」自動登錄完整實戰

     編輯:PHP 相關知識

核心機制對比

特性SessionCookie
存儲位置服務端(文件/Redis/DB)客戶端瀏覽器
生命週期瀏覽器關閉失效(可配置)可設置具體過期時間
安全性高(數據不暴露)低(可被竄改/竊取)
容量限制受服務端內存/磁盤限制單個 4KB,域名下約 20-50 個
傳輸開銷僅傳 Session ID(極小)每請求攜帶全部數據

Session 關鍵操作

<?php
// 必須在任何輸出前調用
session_start();

// 設置生命週期(服務端 GC 時間,單位秒)
ini_set('session.gc_maxlifetime', 86400); // 1 天
// 客戶端 Cookie 同步過期
session_set_cookie_params(86400, '/', '', true, true); // HTTPS+HttpOnly

// 寫入
$_SESSION['user'] = ['id' => 1001, 'name' => '張三'];

// 讀取
$user = $_SESSION['user'] ?? null;

// 刪除單項
unset($_SESSION['user']);

// 銷毀整個 Session(含文件)
session_destroy(); // 需配合 $_SESSION = [] 釋放內存變量

Cookie 關鍵操作

<?php
// 設置:名、值、過期時間戳、路徑、域、Secure、HttpOnly
setcookie('remember_token', 'a1b2c3d4', [
    'expires' => time() + 2592000, // 30 天
    'path' => '/',
    'domain' => '', // 當前域
    'secure' => true,   // 僅 HTTPS
    'httponly' => true, // 防 XSS
    'samesite' => 'Lax' // CSRF 防護
]);

// 讀取
$token = $_COOKIE['remember_token'] ?? '';

// 刪除(設置過去時間)
setcookie('remember_token', '', ['expires' => time() - 3600, 'path' => '/']);

// 存儲陣列/對象:序列化 + Base64
$cookieData = base64_encode(serialize(['uid' => 1001, 'exp' => time() + 86400]));
setcookie('user_data', $cookieData, ['expires' => time() + 86400, 'path' => '/']);
// 讀取還原
$data = unserialize(base64_decode($_COOKIE['user_data'] ?? ''));

自動登錄完整流程

  1. 登錄頁:驗證賬號密碼 → 生成隨機 Token → 寫入 DB(user_id, token, expires_at, user_agent, ip) → 設置 Cookie remember_token → 寫入 Session → 跳轉首頁。
  2. 訪問受保護頁:
    function checkAuth(): ?array {
        // 1. Session 有效直接返回
        if (!empty($_SESSION['user'])) return $_SESSION['user'];
    
        // 2. 無 Session,檢查 Cookie Token
        $token = $_COOKIE['remember_token'] ?? '';
        if (!$token) return null;
    
        // 3. 驗證 Token(防時序攻擊用 hash_equals)
        $record = DB::query("SELECT * FROM remember_tokens WHERE token = ? AND expires_at > NOW()", $token);
        if (!$record || !hash_equals($record['user_agent'], $_SERVER['HTTP_USER_AGENT'] ?? '')) {
            // Token 無效/劫持,清理 Cookie
            setcookie('remember_token', '', ['expires' => time() - 3600, 'path' => '/']);
            return null;
        }
    
        // 4. 刷新 Token 安全性(可選:輪換 Token)
        // 5. 寫入 Session,返回用戶信息
        $user = getUserById($record['user_id']);
        $_SESSION['user'] = $user;
        return $user;
    }
  3. 退出登錄:
    function logout(): void {
        $token = $_COOKIE['remember_token'] ?? '';
        if ($token) {
            DB::execute("DELETE FROM remember_tokens WHERE token = ?", $token);
            setcookie('remember_token', '', ['expires' => time() - 3600, 'path' => '/']);
        }
        $_SESSION = [];
        session_destroy();
    }

安全加固清單

  • ✅ 全站 HTTPS,Cookie 設置 Secure、HttpOnly、SameSite=Lax/Strict。
  • ✅ Token 使用 random_bytes(32) 生成,存儲 hash('sha256', $token) 到 DB,防止 DB 洩露導致 Token 被盜用。
  • ✅ 綁定 User-Agent、IP 段(可選),異常時強制失效。
  • ✅ 限制單用戶同時有效 Token 數量(如最多 5 個設備)。
  • ✅ 定期清理過期 Token 記錄。
  • ✅ Session 存儲建議遷移至 Redis,支援集群、TTL 自動過期。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved