「記住用戶名」是提升用戶體驗的常見功能:用戶勾選後,下次訪問登錄頁時用戶名自動填入,僅需輸入密碼。本文通過完整的 login.php 與 admin.php 兩文件協作,演示如何使用 PHP 原生 Cookie 實現此功能,並說明關鍵安全細節。
login.php → 檢查 Cookie 中是否存在 username → 有則自動填入輸入框admin.phpadmin.php 驗證帳密 → 成功則根據勾選狀態:<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>用戶登錄</title>
</head>
<body>
<?php
/**
* 從 Cookie 獲取已保存的用戶名
* @return string 用戶名或空字符串
*/
function getCookieUsername(): string {
return $_COOKIE['username'] ?? '';
}
?>
<form action="admin.php" method="post">
<label>用戶名:
<input type="text" name="username" value="<?php echo htmlspecialchars(getCookieUsername()); ?>">
</label><br>
<label>密碼:
<input type="password" name="pwd">
</label><br>
<label>
<input type="checkbox" name="yes" value="1"> 是否保存用戶名
</label><br>
<input type="submit" name="sub" value="登錄">
</form>
</body>
</html>
關鍵點:使用 htmlspecialchars() 防止 XSS 攻擊;?? 空合併運算符簡化判斷邏輯。
<?php
// 僅演示邏輯,實際項目請使用預處理語句防止 SQL 注入
if (!empty($_POST['sub']) && $_POST['username'] === 'admin') {
echo "歡迎 " . htmlspecialchars($_POST['username']) . " 登錄成功<br>";
if (!empty($_POST['yes'])) {
// 保存 30 天:time() + 3600*24*30
setcookie('username', $_POST['username'], time() + 2592000, '/', '', false, true);
} else {
// 刪除 Cookie:設為過去時間
setcookie('username', '', time() - 3600, '/', '', false, true);
}
} else {
echo "賬號錯誤,請重新輸入<br>";
}
echo "<a href='login.php'>返回登錄頁面</a>";
?>
安全增強說明:
setcookie 最後三個參數:path、domain、secure(僅 HTTPS 傳輸)、httponly(防 JS 讀取,緩解 XSS)secure 和 httponly僅存用戶名屬於基礎體驗優化。若需實現「免密自動登錄」(記住我),建議採用 Token + 數據庫 方案:
remember_token,存入數據庫(關聯 user_id、過期時間、User-Agent 等指紋)user_id:remember_token(加密簽名)| 現象 | 可能原因 | 解決方案 |
|---|---|---|
| Cookie 不生效 | 輸出內容前已有輸出(含 BOM、空白行) | 確保 setcookie 在任何 echo/HTML 之前調用 |
| 跨子域名不共享 | 未設定 domain 參數 | 設定 domain=.example.com 共享主域及所有子域 |
| HTTPS 下 Cookie 丟失 | 未設定 secure=true | 生產環境強制 secure 並遷移至全站 HTTPS |