保護圖片資源不被未授權訪問或盜鏈,需從 Web 服務器層、PHP 應用層雙重防護。本文整理 Apache/Nginx 配置、PHP 代理輸出、權限驗證的完整實作方案。
# 禁止目錄列表 Options -Indexes # 拒絕所有直接訪問 Order Deny,Allow Deny from all Allow from localhost
location /images/ {
root /usr/local/nginx/html;
auth_basic "Restricted Area";
auth_basic_user_file /usr/local/nginx/conf/htpasswd;
}
生成密碼檔:htpasswd -c /usr/local/nginx/conf/htpasswd username
將圖片放在不可直接訪問的目錄,通過 PHP 腳本驗證權限後讀取檔案內容並輸出正確 Header。
<?php
class ImageProxy {
private $src;
private $data;
private $mime;
public function setSource($path) {
$this->src = $path;
}
public function output() {
// 1. 權限檢查(Session、Token、IP 白名單等)
if (!$this->checkAuth()) {
header('HTTP/1.1 403 Forbidden');
exit('Access Denied');
}
// 2. 讀取圖片二進制內容
$this->mime = $this->getMime();
$this->data = file_get_contents($this->src);
if ($this->data === false) {
header('HTTP/1.1 404 Not Found');
exit('Image Not Found');
}
// 3. 輸出正確 Header 並輸出內容
header("Content-Type: {$this->mime}");
header("Content-Length: " . strlen($this->data));
header('Cache-Control: public, max-age=3600');
echo $this->data;
}
private function getMime() {
$info = getimagesize($this->src);
return $info['mime'] ?? 'application/octet-stream';
}
private function checkAuth() {
// 實作你的驗證邏輯:檢查 $_SESSION['user_id']、JWT Token、Referer 等
return isset($_SESSION['user_id']); // 示例
}
}
// 使用範例
$proxy = new ImageProxy();
$proxy->setSource('/data/private_images/photo_123.jpg'); // 路徑來自資料庫,用戶不可知
$proxy->output();
SetEnvIfNoCase Referer "^https://www.example.com/" local_ref=1
<FilesMatch "\.(gif|jpg|png)$">
Order Allow,Deny
Allow from env=local_ref
</FilesMatch>
顯示預設防盜鏈圖片:
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^https://(www\.)?example.com/.*$ [NC]
RewriteRule \.(gif|jpg|png)$ https://www.example.com/no_hotlink.png [R,L]
location ~* \.(gif|jpg|png)$ {
valid_referers none blocked example.com *.example.com;
if ($invalid_referer) {
return 403; # 或 rewrite 到預設圖片
}
}
| 層級 | 方案 | 優點 | 缺點 |
|---|---|---|---|
| Web Server | 目錄封鎖 + auth_basic | 效能最好、無 PHP 開銷 | 靈活度低、難以整合複雜業務邏輯 |
| PHP 代理 | 權限驗證 + 輸出二進制 | 完全可控、支援任意業務邏輯 | 消耗 PHP 進程、需注意大檔案記憶體 |
| Referer 檢查 | Apache/Nginx 防盜鏈 | 簡單有效阻擋大多數盜鏈 | Referer 可偽造、非絕對安全 |
建議組合:靜態資源走 Nginx 直接防盜鏈;私有/敏感圖片走 PHP 代理並整合業務權限系統;關鍵目錄在 Web Server 層直接 Deny all。