簡體   English   中英

如何防止非成員使用PHP直接訪問私有內容

[英]How to prevent non members from directly accessing private content with PHP

我知道.htaccess Apache保護文件夾不受非成員訪問的方法,但想知道如何僅使用PHP才能做到。

檢查會話變量可以保護php頁面,但是直接訪問照片和pdf有時似乎被忽略了。 例如,如果我將直接鏈接從Facebook復制到照片,然后注銷,然后將瀏覽器定向到照片的URL,則表明沒有問題。

Rapidshare之類的網站如何防止直接訪問其內容?

我知道有一種在Apache中設置變量的方法。 也許有一種方法可以使用Apache檢查會話變量?

從問題和評論看來,您似乎在追求看起來像直接訪問的URL,但通過PHP腳本來允許授權來下載它們。 我不知道您當前的目錄結構,所以我將為該答案的測試用例做一個補充-盡管有一個小的清單:

public-html/
    content/        <- where the actual files are
        .htaccess   <- to deny access to the directory
    .htaccess       <- the one created here
    download.php    <- download script

由此,我們將假定所有文件都位於/content ,並且“直接鏈接”看起來像是要進入/file

/content/.htaccess

deny from all

下一個帶有第一個RewriteRule的注釋,因此不會覆蓋已經存在的普通文件,而先前的.htaccess阻止訪問該目錄中的文件。 如果您已經使用了.htaccess ,則重要的規則是最后一個規則,如果匹配則停止處理,因此請將其相應地放置在現有的.htaccess

/.htaccess

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} -s [OR]
    RewriteCond %{REQUEST_FILENAME} -l [OR]
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule ^.*$ - [NC,L]

    RewriteRule ^file/(.+)$ download.php?file=$1 [L]
</IfModule>

將其放置在適當位置后,如果轉到/file/myDocument.pdf ,則看起來像是直接訪問文件,並且將其發送到類似download.php?file=myDocument.pdf的腳本。

從那里開始,只需創建要使用的下載腳本即可。 我要發布的是此處的Armand Niculescu的修改版本。 我僅在此處發布相關部分( 可以在PasteBin找到整個部分,您可以在此處修改此處發布的部分以適合您的需求):

/******************************
 * PERFORM AUTHORIZATION HERE *
 *   The following is added   *
 ******************************/
if($_SESSION['validated'] !== true) {
    //Not authorized to download, send header and exit
    header("HTTP/1.0 401 Unauthorized");
    exit;
}

我還對8行以下的正確文件路徑進行了另一次較小的編輯:

$file_path  = './content/' . $file_name;

到此為止,這個小例子說明了如何獲得有效的下載腳本並使它看起來像直接文件訪問一樣。

從您的問題中得知,您已經知道如何保護文件夾免受直接訪問,以及如何保護php腳本。 因此,您需要的是受保護的php腳本,可提供對文件的間接訪問(如注釋中已提到的)。

創建此下載腳本時,您應該記住一些重要的細節:

  • 提供MIME類型。 盡管在許多情況下, header("Content-Type: application/octet-stream")就足夠了
  • 告訴客戶端下載文件(而不是顯示文件)並提供文件名: header('Content-Disposition: attachment; filename="' . basename($path) . '"')
  • 提供文件大小: header("Content-Length: " . filesize($path));
  • 為了避免大文件出現問題,您應該使用類似以下的內容而不是readfile

     $file = fopen($path, 'r'); flush(); while (!feof($file)) { print(fread($file, 4096)); flush(); } fclose($file); 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM