原生 setcookie() 與 $_COOKIE 雖然簡單,但缺乏安全機制:值容易被竄改、無完整性驗證、路徑/域名管理分散。本文提供一組封裝函式,內建 MD5 簽名驗證,防止用戶端偽造 Cookie 資料。
PutCookie()function PutCookie($key, $value, $kptime = 0, $pa = "/") {
global $cfg_cookie_encode;
setcookie($key, $value, time() + $kptime, $pa);
// 寫入簽名:取前 16 位 MD5,金鑰含伺服器端密鑰 $cfg_cookie_encode
setcookie($key . '__ckMd5', substr(md5($cfg_cookie_encode . $value), 0, 16), time() + $kptime, $pa);
}
關鍵點:
值 + 簽名$cfg_cookie_encode,用戶端無法偽造/,全站可用$kptime=0 表示瀏覽器關閉即失效(Session Cookie)GetCookie()function GetCookie($key) {
global $cfg_cookie_encode;
if (!isset($_COOKIE[$key]) || !isset($_COOKIE[$key . '__ckMd5'])) {
return '';
}
// 驗證簽名
if ($_COOKIE[$key . '__ckMd5'] != substr(md5($cfg_cookie_encode . $_COOKIE[$key]), 0, 16)) {
return ''; // 簽名不符,資料被竄改
}
return $_COOKIE[$key];
}
驗證失敗時回傳空字串,等同於 Cookie 不存在,避免使用到被竄改的資料。
DropCookie()function DropCookie($key) {
setcookie($key, '', time() - 360000, "/");
setcookie($key . '__ckMd5', '', time() - 360000, "/");
}
將過期時間設為過去(360000 秒約 4 天前),瀏覽器會自動刪除。
// 設定密鑰(通常放在設定檔)
$cfg_cookie_encode = 'your_secret_key_here';
// 寫入
PutCookie('user_id', 12345, 3600); // 1 小時有效
// 讀取
$uid = GetCookie('user_id');
if ($uid) {
echo "歡迎回來,用戶 ID:$uid";
} else {
echo "Cookie 無效或已過期";
}
// 登出時刪除
DropCookie('user_id');
setcookie($key, $value, $expire, $path, $domain, $secure, true);