HTTP 基本認證透過 WWW-Authenticate 標頭要求瀏覽器彈出登入對話框,使用者輸入的帳密會以 Base64 編碼放在 Authorization 標頭傳回伺服器。PHP 可透過 $_SERVER['PHP_AUTH_USER'] 和 $_SERVER['PHP_AUTH_PW'] 取得解碼後的憑證。
<?php
// 設定合法帳密(實際專案應從資料庫/設定檔讀取,並使用密碼雜湊驗證)
$validUsers = [
'admin' => password_hash('securePass123', PASSWORD_DEFAULT),
'editor' => password_hash('editPass456', PASSWORD_DEFAULT),
];
$realm = 'My Private Area';
// 檢查是否已提供認證資訊
if (!isset($_SERVER['PHP_AUTH_USER'])) {
// 要求認證
header('WWW-Authenticate: Basic realm="' . $realm . '"');
header('HTTP/1.0 401 Unauthorized');
exit('需要有效憑證才能存取!');
}
// 驗證帳密
$user = $_SERVER['PHP_AUTH_USER'];
$pass = $_SERVER['PHP_AUTH_PW'];
if (isset($validUsers[$user]) && password_verify($pass, $validUsers[$user])) {
// 認證成功
echo "歡迎進入私有區域,{$user}!";
// 此處放入受保護的內容或邏輯
} else {
// 認證失敗,再次要求
header('WWW-Authenticate: Basic realm="' . $realm . '"');
header('HTTP/1.0 401 Unauthorized');
exit('帳號或密碼錯誤,請重試。');
}
?>
Basic Auth 將帳密以 Base64 傳輸(極易解碼),絕對不能在明文 HTTP 上使用。生產環境強制啟用 TLS。
範例使用 password_hash() + password_verify(),絕不儲存明文密碼。
<?php
// 簡易速率限制(實際建議用 Redis/資料庫儲存嘗試次數)
session_start();
$key = 'auth_attempts_' . $_SERVER['REMOTE_ADDR'];
$_SESSION[$key] = ($_SESSION[$key] ?? 0) + 1;
if ($_SESSION[$key] > 5) {
header('HTTP/1.0 429 Too Many Requests');
exit('嘗試次數過多,請稍後再試。');
}
// 成功登入後重置
if (/* 認證成功 */) {
unset($_SESSION[$key]);
}
?>
<?php
header('Cache-Control: no-store, no-cache, must-revalidate, private');
header('Pragma: no-cache');
?>
| 優點 | 缺點 |
|---|---|
| 無需資料庫/Session,極簡部署 | 每次請求都傳送帳密,效能稍低 |
| 瀏覽器原生支援,無需前端配合 | 無法自訂登入介面/登出機制 |
| 適合內部工具、API、階段性環境 | 不支援 MFA、OAuth、SSO 等現代認證 |
若需保護靜態檔案或整個目錄,仍建議使用 Apache .htaccess + .htpasswd:
# .htaccess AuthType Basic AuthName "Restricted Area" AuthUserFile /path/to/.htpasswd Require valid-user
PHP 實作 Basic Auth 適合動態邏輯控制,靜態資源保護仍首選 Web Server 層面方案。