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

PHP 防盜鏈完整方案:從 PHP 簡易驗證到 Apache/Nginx/IIS 伺服器層阻擋

     編輯:PHP 綜合知識

圖片、下載檔案被外站直接引用(盜鏈)會消耗頻寬、洩露資源。本文系統整理三層防禦體系:**PHP 應用層驗證(靈活但可繞過)、Apache/Nginx 伺服器層重寫(高效能、標準)、IIS 重寫模組**,並提供可直接部署的配置範例。

第一層:PHP 應用層驗證(簡易、可繞過)

原理:檢查 $_SERVER['HTTP_REFERER'] 是否包含本站域名,或驗證 Session 標記。缺點:Referer 可偽造、用戶可關閉發送、代理/防火牆可能剝離。

<?php
// 入口檔案或圖片輸出腳本開頭
session_start();
$referer = parse_url($_SERVER['HTTP_REFERER'] ?? '', PHP_URL_HOST);
$allowedHosts = ['example.com', 'www.example.com', 'static.example.com'];

if (empty($referer) || !in_array($referer, $allowedHosts)) {
    // 可選:返回 403、透明圖、預設圖、重導向
    header('HTTP/1.1 403 Forbidden');
    exit('Hotlinking not allowed');
}
// 正常輸出圖片/檔案
readfile('/path/to/real/file.jpg');

第二層:Apache mod_rewrite 阻擋(推薦生產環境)

在 .htaccess 或 httpd.conf <Directory> 區塊:

# 啟用重寫引擎
RewriteEngine On

# 允許空 Referer(直接輸入網址、書籤、某些代理)
RewriteCond %{HTTP_REFERER} ^$ [OR]

# 允許本站域名(含子域名、協議)
RewriteCond %{HTTP_REFERER} ^https?://(www\.)?example\.com/ [NC]

# 允許特定合作夥伴域名(可選)
# RewriteCond %{HTTP_REFERER} ^https?://(partner\.com|api\.partner\.com)/ [NC]

# 符合上述條件者放行,否則攔截
RewriteRule \.(jpe?g|png|gif|webp|pdf|zip|rar)$ - [F,NC,L]

# 進階:返回指定防盜鏈圖片(需確保該圖不觸發規則)
# RewriteRule \.(jpe?g|png|gif)$ /images/hotlink-denied.png [R=302,NC,L]

第三層:Nginx 阻擋(高效能、配置簡潔)

location ~* \.(jpe?g|png|gif|webp|pdf|zip|rar)$ {
    valid_referers none blocked
        example.com
        www.example.com
        *.example.com
        partner.com;
    if ($invalid_referer) {
        return 403;               # 或 rewrite /hotlink-denied.png redirect;
        # return 302 /hotlink-denied.png;
    }
    # 可選:添加緩存頭、防盜鏈水印
    expires 30d;
    add_header Cache-Control "public";
}

第四層:IIS URL Rewrite (web.config)

<configuration>
  <system.webServer>
    <rewrite>
      <rules>
        <rule name="Prevent Hotlinking" stopProcessing="true">
          <match url=".*\.(jpe?g|png|gif|webp|pdf|zip|rar)$" />
          <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
            <add input="{HTTP_REFERER}" pattern="^$" negate="true" />
            <add input="{HTTP_REFERER}" pattern="^https?://(www\.)?example\.com/" negate="true" />
          </conditions>
          <action type="CustomResponse" statusCode="403" statusReason="Forbidden" statusDescription="Hotlinking not allowed" />
          <!-- 或重導向到防盜鏈圖片 -->
          <!-- <action type="Redirect" url="/hotlink-denied.png" redirectType="Found" /> -->
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>

進階策略:Token/簽名 URL(最高安全性)

對於付費資源、私密檔案,Referer 驗證不足夠。採用**帶期限簽名的一次性 URL**:

// 生成簽名下載連結 (Laravel 範例)
$url = URL::temporarySignedRoute(
    'download.file', now()->addMinutes(30), ['file' => $filename]
);
// 輸出:/download/file/abc123?signature=xxx&expires=1234567890

// 路由中間件自動驗證簽名與過期時間
Route::get('/download/file/{file}', 'DownloadController@download')
    ->name('download.file')
    ->middleware('signed');

優點:無 Referer 依賴、可控過期、可限制 IP/用戶、支援 CDN 邊緣驗證。

方案選擇建議

場景推薦方案理由
靜態資源(圖片、CSS、JS)Nginx/Apache valid_referers / RewriteRule零 PHP 開銷、CDN 邊緣可直接執行
動態生成圖表/驗證碼PHP Session/Token 驗證需結合業務邏輯(如登入狀態)
付費/私密下載簽名 URL + 伺服器層雙重校驗最高安全性、可審計、支援 CDN
虛擬主機無法修改伺服器配置PHP Referer 檢查 + .htaccess (Apache)唯一可行途徑

總結

防盜鏈應遵循**「越前端越好、越靜態越好」**原則:優先在 Nginx/Apache/CDN 層以 valid_referers/RewriteRule 阻擋 99% 盜鏈;動態資源用 PHP Session/Token 輔助;核心付費資源務必升級為**簽名 URL**。切勿單獨依賴 HTTP_REFERER,它不可靠且易繞過。

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