登入驗證是 Web 應用基礎功能。本文展示一個極簡的 checklogin 類別,透過建構子接收帳密,查詢資料庫比對,成功則寫入 Session 並跳轉,失敗則彈窗返回。
<?php
class checklogin {
var $name, $pwd;
function __construct($username, $password) {
$this->name = $username;
$this->pwd = $password;
}
function checkinput() {
global $db;
$sql = "select * from tb_manager where name='$this->name' and pwd='$this->pwd'";
$res = $db->query($sql);
$info = $db->fetch_array($res);
if ($info['name'] == $this->name and $info['pwd'] == $this->pwd) {
$_SESSION['admin_name'] = $info['name'];
$_SESSION['pwd'] = $info['pwd'];
echo "<script>alert('登錄成功!);window.location.href='index.php';</script>";
} else {
echo "<script language='javascript'>alert('登錄失敗!');history.back();</script>";
exit;
}
}
}
?>
| 問題 | 風險等級 | 說明 |
|---|---|---|
| 明文密碼儲存與比對 | 🔴 致命 | 資料庫儲存明文,SQL 直接比對明文,洩露即全洩露 |
| SQL 注入漏洞 | 🔴 致命 | 帳密直接拼接 SQL,可繞過驗證或執行任意指令 |
| Session 固定攻擊 | 🟠 高 | 未重新生成 Session ID,易遭竊取 |
| XSS 輸出未轉義 | 🟠 高 | 直接輸出 JS 字串,若帳號含惡意腳本將執行 |
| 暴力破解無防護 | 🟡 中 | 無嘗試次數限制、驗證碼、IP 封鎖機制 |
| 使用已棄用 mysql_* 函數 | 🔴 致命 | PHP 7+ 不支援,必須遷移 |
password_hash() 儲存,password_verify() 驗證。session_regenerate_id(true) 登入後重新生成 ID,設定 httponly/secure/samesite 旗標。htmlspecialchars() 防止 XSS。class AuthService {
private $pdo;
public function __construct(PDO $pdo) { $this->pdo = $pdo; }
public function attempt(string $username, string $password): bool {
$stmt = $this->pdo->prepare("SELECT id, password_hash FROM users WHERE username = ?");
$stmt->execute([$username]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
if ($user && password_verify($password, $user['password_hash'])) {
session_regenerate_id(true);
$_SESSION['user_id'] = $user['id'];
return true;
}
return false;
}
}
原範例僅適合理解基本流程,絕不可用於生產環境,請務必採用成熟認證框架(Laravel Auth、Symfony Security 等)或依照上述原則自行實現。