1. 程式人生 > >使用 Nginx 的 X-Sendfile 機制控制檔案訪問許可權(php版)

使用 Nginx 的 X-Sendfile 機制控制檔案訪問許可權(php版)

BBS或者網站經常會有隻有你有許可權才能看到這個頁面,或者下載這個資源,日前探訪了nginx伺服器怎麼實現這個檔案控制的,用到了x-sendfile。

一、什麼是 X-Sendfile?

X-Sendfile 是一種將檔案下載請求由後端應用轉交給前端 web 伺服器處理的機制,它可以消除後端程式既要讀檔案又要處理髮送的壓力,從而顯著提高伺服器效率,特別是處理大檔案下載的情形下。

X-Sendfile 通過一個特定的 HTTP header 來實現:在 X-Sendfile 頭中指定一個檔案的地址來通告前端 web 伺服器。當 web 伺服器檢測到後端傳送的這個 header 後,它將忽略後端的其他輸出,而使用自身的元件(包括 快取頭 和 斷點重連 等優化)機制將檔案傳送給使用者。

不過,在使用 X-Sendfile 之前,我們必須明白這並不是一個標準特性,在預設情況下它是被大多數 web 伺服器禁用的。而不同的 web 伺服器的實現也不一樣,包括規定了不同的 X-Sendfile 頭格式。如果配置失當,使用者可能下載到 0 位元組的檔案。

使用 X-Sendfile 將允許下載非 web 目錄中的檔案(例如/root/),即使檔案在 .htaccess 保護下禁止訪問,也會被下載。

不同的 web 伺服器實現了不同的 HTTP 頭
SENDFILE 頭 使用的 WEB 伺服器
X-Sendfile Apache, Lighttpd v1.5, Cherokee
X-LIGHTTPD-send-file Lighttpd v1.4
X-Accel-Redirect Nginx, Cherokee

使用 X-SendFile 的缺點是你失去了對檔案傳輸機制的控制。例如如果你希望在完成檔案下載後執行某些操作,比如只允許使用者下載檔案一次,這個 X-Sendfile 是沒法做到的,因為後臺的 php 指令碼並不知道下載是否成功。

二、NGINX怎樣使用?

        Nginx 預設支援該特性,不需要載入額外的模組。只是實現有些不同,需要傳送的 HTTP 頭為 X-Accel-Redirect。另外,需要在配置檔案中做以下設定

    location /game/ {
         internal;
         alias /data/app/php/open.game.liebao.cn/default/game/;    //檔案可以放到別的目錄
         error_page 404 =200 @backend;                                         // 如果訪問出現404轉發到後臺伺服器
     }   
    location @backend {
       #proxy_pass http://test.open.game.cn;                       // 可以客戶端發起請求時,將這個目錄的請求代理到其他機器 


        rewrite ^/game/(.*)$ /read_file.php?fn=$1 last;                 // 客戶端發起請求時,rewritet跳轉到後臺程式
    }   

     internal 表示這個路徑只能在 Nginx 內部訪問,不能用瀏覽器直接訪問防止未授權的下載。

三、php程式怎樣使用?

 <?php
$pay = 2;                                   
$path = $_GET["fn"];   //獲取使用者訪問的url引數
if ($pay>1)                   //付過錢的 加上X-Accel-Redirect的頭,就能訪問到,否則無法訪問
{
        // header("Content-Type: application/octet-stream");            //檔案下載時候用到
         header("X-Accel-Redirect: /game/".$path);
}
?> 如果加上了加上X-Accel-Redirect的頭,這樣使用者就會下載到 /game 這個路徑下的檔案。我們的檔案許可權控制就實現了。