6

私は、十分な特権を持っている人々にダウンロードしてほしいすべてのファイルのゲートキーパーとして機能するphpファイルを持っています。

私が使用するコードは、ファイルをユーザーにスローします

header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header("Content-disposition: attachment; filename=\"".$public_filename."\""); 
header("Content-Transfer-Encoding: Binary"); 
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header("Content-length: ".$f_filesize); 
readfile($file_path);

ほとんどのファイルはかなり大きいです....400mb-10GB。

これを行うには、実際の場所とファイル名を秘密にしておくとよいでしょう。そうすれば、人々はファイルに直接リンクすることはできませんが、download.php?file = IDゲートキーパーを介してリンクする必要がありますか?

ありがとう

編集:私はユーザー認証を行う方法を尋ねていません、それはすべて行われます。私のやり方は大規模に良い考えかと尋ねるだけです。10GBのファイルを読み続けると、メモリの問題が発生する可能性があるようです。

4

5 に答える 5

10

OK、約 400Mb ~ 10Gb のファイルを php で送信するのは良くありません。使用しているWebサーバーが実際にファイルを提供できるようにする必要があります。

これは、どれだけ安全である必要があるかにかかっています。頭に浮かぶ最も簡単な解決策 (ただし、最も安全とは言えません) は、元のファイルにリンクする長いランダムな名前のシンボリック リンクを使用することです。一定の時間が経過すると、シンボリック リンクは期限切れになり、削除されます。各ユーザーは、ダウンロードしているファイルへの独自のシンボリック リンク (または「トークン」) を取得します。これが Windows 環境でどのように機能するかはわかりませんが、UNIX ではとにかく簡単です。

ここにいくつかの擬似コードがあります:

if($user->isAllowedToDownload($file)){
    $token = md5($user->name . $file->name . time() . $someGoodRandomValue);
    symlink($file, $download_path . $token);
    header("Location: $download_url$token"); 
}

次に、古いシンボリック リンクを消去する cron ジョブが必要です。また、Web サーバーがシンボリック リンクをたどるように設定されていることを確認する必要があります。できれば、これらのダウンロード トークンが作成されたフォルダーに対してのみです。

そのため、ユーザーが要求domain.com/download?file=bigfile.mp4すると、Web サーバーのパブリック スペースの外にある実際のファイルを指すシンボリック リンクが Web サーバーのパブリック スペースに作成されます。ユーザーは多分にリダイレクトされdomain.com/getFile/ab739babec890103bdbca72、それによりWebサーバーがファイルを提供します。現在、ユーザーがファイルの URL を推測するのは非常に困難です。これが「セキュリティ」です。

于 2010-06-09T22:46:37.177 に答える
2

あなたはすでにそれをやっています-それ$public_filenameはあなたがそれを呼びたいものです、readfile($ file_path)部分はファイルです-その場所は公開されていません。それを過ぎると、ドキュメントルートの上にある可能性があります。

于 2010-06-09T22:26:55.663 に答える
1

なんらかの方法でそれらを認証し(HTMLフォーム、HTTP基本認証など)、次に、download.phpスクリプトがチェックできるセッションフラグを設定する必要があります。これは、人々がファイルをダウンロードして自分で配布することを妨げるものではないことに注意してください。

実際のファイルに直接アクセスできないように、Webサーバーを構成する必要があります。

それ自体はメモリの問題を引き起こすことはありません。readfileはファイルをメモリに読み込みません。ただし、PHP使用するとオーバーヘッドが発生します。X-Sendfileを使用すると、この遅延の一部を解消できます。

于 2010-06-09T22:25:55.750 に答える
1
  1. HTTP経由でアクセスできない場所にファイルを配置します。
  2. ファイルパスを使用してファイルIDのデータベーステーブルを作成します。
  3. ファイルIDを介してファイルにリンクします(上記のように、download.php?fileID = 0000)。
  4. ???
  5. 利益。

以前(何年も前に)これを行った人として、これがサーバーに与えるメモリの影響を考慮する必要があります。このreadfile機能はその時点では使用できなかったため、メモリを考慮するために特別なことをする必要がない可能性があります。

于 2010-06-09T22:29:09.970 に答える
1

あなたの方法はメモリの問題を引き起こしますが、ファイルをチャンクで読み書きすることは可能です。ファイルの各チャンクの後で、 flush()関数を使用する必要があります。echoダウンロードを再開して、もう少し手間をかけることもできます。それでも、これはCPUを大量に消費するアプローチです。

より簡単で優れた解決策は、モジュールを介してapacheとlighttpdの両方でサポートされている「x-sendfile」ヘッダータグを使用することです。次のように、ヘッダーにファイル名を指定するだけです。

header('X-Sendfile: filename-on-your-file-system');

lighttpdのリンク:

http://redmine.lighttpd.net/projects/lighttpd/wiki/X-LIGHTTPD-send-file

于 2010-06-09T23:32:35.103 に答える