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

PHP 控制圖片訪問權限與防盜鏈完整方案

     編輯:PHP 相關知識

PHP 控制圖片訪問權限與防盜鏈完整方案

保護圖片資源不被未授權訪問或盜鏈,需從 Web 服務器層、PHP 應用層雙重防護。本文整理 Apache/Nginx 配置、PHP 代理輸出、權限驗證的完整實作方案。

一、Web 服務器層直接封鎖目錄

Apache (.htaccess)

# 禁止目錄列表
Options -Indexes
# 拒絕所有直接訪問
Order Deny,Allow
Deny from all
Allow from localhost

Nginx (ngx_http_auth_basic_module)

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 代理輸出圖片(核心邏輯)

將圖片放在不可直接訪問的目錄,通過 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();

三、Apache 防盜鏈

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]

四、Nginx 防盜鏈

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。

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