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

PHP 防盜鏈實戰:從 Session 驗證到 Apache/Nginx 服務器級方案

     編輯:PHP 相關知識

圖片與文件防盜鏈完整解決方案

防盜鏈核心在於識別請求來源,僅允許本站頁面引用靜態資源。本文對比 PHP 應用層、Apache、Nginx、IIS 多層級防盜鏈方案,幫助你選擇最適合的部署策略。

方案一:PHP 應用層驗證(靈活但有性能開銷)

利用 $_SERVER['HTTP_REFERER'] 判斷來源,配合 Session 防止直接訪問。適合無服務器配置權限的虛擬主機環境。

<?php
// 入口文件(如 index.php)設置 Session 標記
session_start();
$_SESSION['allow_access'] = true;
?>
<?php
// 圖片輸出腳本(如 show_img.php)
session_start();
$referer = parse_url($_SERVER['HTTP_REFERER'] ?? '');

// 雙重校驗:Session 標記 + 來源域名
if (empty($_SESSION['allow_access']) || $referer['host'] !== $_SERVER['HTTP_HOST']) {
    header('HTTP/1.1 403 Forbidden');
    exit('Access Denied');
}

// 輸出圖片
$file = '/path/to/images/' . basename($_GET['img']);
if (is_file($file)) {
    header('Content-Type: ' . mime_content_type($file));
    readfile($file);
}
?>

缺點:Referer 可偽造、防火牆/代理可能剔除;PHP 處理靜態文件佔用進程,高併發下效能差。

方案二:Apache mod_rewrite 服務器級防盜鏈(推薦)

在 .htaccess 或 httpd.conf 中配置,性能最優,無需啟動 PHP 進程。

<!-- 僅允許本站與空 Referer(直接輸入網址)訪問 -->
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?yourdomain\.com [NC]
RewriteRule \.(gif|jpg|jpeg|png|bmp|webp)$ /static/forbidden.png [R=302,L]

<!-- 進階:返回 403 而非跳轉 -->
RewriteRule \.(gif|jpg|png)$ - [F,NC]

關鍵點:

  • !^$ 允許無 Referer 請求(瀏覽器直接打開圖片網址),視業務決定是否保留。
  • [NC] 大小寫不敏感匹配域名。
  • 建議將防盜鏈圖片放在 /static/ 目錄並排除該目錄規則,避免無限循環。

方案三:Nginx 防盜鏈(高性能首選)

Nginx 原生 valid_referers 指令語義清晰,效能極高。

location ~* \.(gif|jpg|jpeg|png|bmp|webp|pdf|zip|rar)$ {
    valid_referers none blocked yourdomain.com *.yourdomain.com;
    if ($invalid_referer) {
        return 403;              # 或 rewrite /static/forbidden.png redirect;
        # rewrite ^/static/forbidden.png last; # 內部跳轉避免 302
    }
    # 可選:緩存控制
    expires 30d;
    add_header Cache-Control "public";
}
  • none:允許無 Referer;blocked:允許被防火牆過濾的 Referer;
  • 域名支援通配符 *.yourdomain.com;
  • 返回 403 比 302 重定向更節省頻寬與延遲。

方案四:IIS URL Rewrite(Windows 服務器)

在 web.config 中配置:

<rule name="AntiHotlink" stopProcessing="true">
    <match url=".*\.(gif|jpg|png|pdf|zip)$" />
    <conditions>
        <add input="{HTTP_REFERER}" pattern="^$" negate="true" />
        <add input="{HTTP_REFERER}" pattern="^https?://(www\.)?yourdomain\.com" negate="true" />
    </conditions>
    <action type="CustomResponse" statusCode="403" statusReason="Forbidden" statusDescription="Hotlinking not allowed" />
</rule>

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

對於付費資源、私有文件,Referer 檢查不夠安全。採用帶過期時間的簽名 URL:

<?php
// 生成簽名鏈接
function signedUrl($file, $expire = 300) {
    $secret = 'your_secret_key';
    $expireTime = time() + $expire;
    $signature = hash_hmac('sha256', $file . $expireTime, $secret);
    return "/download.php?file=$file&expire=$expireTime&sign=$signature";
}

// download.php 驗證
$file = $_GET['file'];
$expire = (int)$_GET['expire'];
$sign = $_GET['sign'];
if (time() > $expire) exit('Link expired');
$expected = hash_hmac('sha256', $file . $expire, 'your_secret_key');
if (!hash_equals($expected, $sign)) exit('Invalid signature');
// 輸出文件...
?>

此方案無視 Referer,適合 API、CDN 回源、私有雲場景。

總結選型建議

方案性能安全性維護成本適用場景
PHP Session + Referer低低低虛擬主機、無服務器權限
Apache mod_rewrite高中中Apache 環境、靜態資源防盜鏈
Nginx valid_referers極高中低Nginx 環境、高併發靜態資源
簽名 URL (Token)中極高高付費資源、私有文件、API 下載

生產建議:靜態資源走 Nginx/Apache 層防盜鏈,動態/私有資源用簽名 URL,雙管齊下兼顧性能與安全。

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