首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 防盜鏈與圖片目錄存取控制兩大實戰方案

     編輯:PHP 綜合知識

圖片被外站盜鏈不僅侵權,更消耗頻寬與伺服器資源。本文提供兩種不同層級的防護方案:**Apache Rewrite 規則**(邊緣攔截)與 **PHP 代理讀取**(應用層權限控制),並附 Nginx 設定參考。

方案一:Apache .htaccess 重導向防盜鏈(推薦靜態資源)

將下列內容存為 .htaccess 放入圖片目錄(如 /images/ 或 /uploads/)。

RewriteEngine On
# 允許空 Referer(直接在瀏覽器輸入圖片網址)
RewriteCond %{HTTP_REFERER} !^$ [NC]
# 允許自家域名(含子域名)
RewriteCond %{HTTP_REFERER} !^https?://(.+\.)?example\.com [NC]
# 允許主流搜尋引擎爬蟲(SEO 需求)
RewriteCond %{HTTP_REFERER} !^https?://(.+\.)?(google|baidu|bing|yahoo)\.com [NC]
# 允許 RSS 閱讀器
RewriteCond %{HTTP_REFERER} !^https?://(.+\.)?(feedly|feedburner)\.com [NC]

# 符合上述所有條件(即非授權來源)→ 替換為預設圖片
RewriteRule \.(jpg|jpeg|png|gif|bmp|webp|svg)$ /images/hotlink-placeholder.png [R,NC,L]

# 可選:將請求轉向外部圖床分流流量
# RewriteRule ^(.*)$ https://img-cdn.example.com/$1 [L]

關鍵指令解析

  • RewriteCond %{HTTP_REFERER} !^$:允許無 Referer 請求(使用者直接開圖)。
  • [NC]:大小寫不敏感。
  • [R,NC,L]:R=302 重導向、L=最後一條規則。
  • 替換圖片**不可**放在同一受保護目錄,否則無限循環。

方案二:PHP 代理讀取 + 目錄權限鎖死(高安全性、動態權限)

適用於:會員專屬圖片、付費內容、加密相簿、防止繞過 Referer 偽造。

1. 伺服器層面封鎖目錄直接存取

Apache:在圖片目錄放入 .htaccess

Options -Indexes
Order Deny,Allow
Deny from all
Allow from 127.0.0.1

Nginx:

location /protected-images/ {
    internal;          # 僅允許內部 redirect (X-Accel-Redirect)
    alias /var/www/protected-images/;
}

2. PHP 代理腳本 image.php

// image.php?id=123&token=xxx
session_start();
// 1. 權限驗證(會員等級、付費狀態、一次性 token 等)
if (!checkAccess($_GET['id'], $_SESSION['user_id'])) {
    header('HTTP/1.1 403 Forbidden');
    exit('存取被拒絕');
}

// 2. 取得實體路徑(資料庫查詢,不直接暴露路徑參數)
$row = db_fetch("SELECT filepath, mime FROM images WHERE id=? AND deleted=0", $_GET['id']);
if (!$row || !file_exists($row['filepath'])) {
    header('HTTP/1.1 404 Not Found');
    exit('圖片不存在');
}

// 3. 輸出圖片
header('Content-Type: ' . $row['mime']);
header('Content-Length: ' . filesize($row['filepath']));
header('Cache-Control: private, max-age=3600'); // 私有快取 1 小時
readfile($row['filepath']); // 高效輸出,不佔用 PHP 記憶體
exit;

3. Nginx X-Accel-Redirect 零拷貝加速(生產環境推薦)

// PHP 僅驗證權限,回傳內部路徑給 Nginx
header('X-Accel-Redirect: /protected-images/' . basename($row['filepath']));
header('Content-Type: ' . $row['mime']);
exit; // Nginx 接管傳輸,PHP 進程立即釋放

Nginx 設定對應 internal location,實現**核心層級零拷貝傳輸**,大幅降低 PHP 記憶體佔用與 CPU。

方案比較與選擇建議

維度Apache RewritePHP 代理 + 權限
部署難度低(僅 .htaccess)中(需改程式、Nginx 配合)
防偽造 Referer弱(Referer 可偽造)強(應用層驗證 Session/Token)
動態權限不支援支援(會員等級、付費、時效)
效能極高(核心層 302)中(PHP 讀檔) → 高(X-Accel-Redirect)
適用場景公開內容防盜鏈、SEO 友善私有/付費/敏感圖片、嚴格存取控制

進階:Nginx ngx_http_auth_basic_module 簡易密碼保護

location /secret-album/ {
    auth_basic "Private Album";
    auth_basic_user_file /etc/nginx/htpasswd; # htpasswd -c /etc/nginx/htpasswd user
}

總結

  • **公開圖片防盜鏈** → Apache Rewrite / Nginx valid_referers 即可,零程式碼改動。
  • **私有圖片權限控制** → 目錄 Deny from all + PHP 代理驗證 + X-Accel-Redirect,安全且高效。
  • **兩者可共存**:公開目錄用 Rewrite,私有目錄用代理,依業務劃分資料夾。

正確選擇並部署防盜鏈策略,能有效保護頻寬成本與智慧財產權,兼顧 SEO 與使用者體驗。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved