How to let users with required permission download a file via php?

前端 未结 5 1255
南旧
南旧 2021-01-03 00:27

I have a php file that acts as a gatekeeper for all the files I want people to download, who ahve sufficient privilages.

The code I use throw the file to the user i

相关标签:
5条回答
  • 2021-01-03 00:42

    Ok, having php send files of around 400Mb–10Gb is not good. You need to somehow let whatever webserver you're using actually serve the files.

    This really comes down to how secure you need it to be. The easiest solution that comes to mind (but far from the most secure) is using symbolic links with long random names that link to the original file. After a certain time the symbolic links expire and are removed. Each user get their own symbolic link (or "token") to the file they're downloading. I'm not sure how this plays out in Windows-environment, but on unix it's fairly straightforward anyway.

    Here's some pseudo code:

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

    Then you need a cron job that cleans out old symbolic links. You also need to make sure the webserver is set to follow symbolic links, preferably only for that folder where these download tokens are created.

    So when the user maybe requests domain.com/download?file=bigfile.mp4 a symbolic link is created in the webservers public space that points to the real file outside the webservers public space. The user gets redirected to maybe domain.com/getFile/ab739babec890103bdbca72 which in turn causes the webserver to serve the file. Now it's very hard for users to try and guess what an URL is for a file, and that's the "security".

    0 讨论(0)
  • 2021-01-03 00:46

    You're already doing that - the $public_filename is what you want it called, the readfile($file_path) part is the file - it's location isn't made public. Past that, it could be above the document root.

    0 讨论(0)
  • 2021-01-03 00:53
    1. Put the files somewhere that is not accessible via HTTP.
    2. Create a database table of file IDs with file paths.
    3. Link to the files via file ID (as you noted above, download.php?fileID=0000).
    4. ???
    5. Profit.

    As someone who did this previously (many years ago), you need to consider the memory impact this will have on your server. The readfile function was not available then, so it is possible you may not need to do anything special for memory considerations.

    0 讨论(0)
  • 2021-01-03 00:59

    Your method will cause memory problems, however it is possible to read and output the file in chunks. You will need to use flush() function after you echo each chunk of file. You can also make resuming downloads to work with a little more effort. Still this is an CPU hungry approach.

    The easier and better solution is to use "x-sendfile" header tag supported by both apache and lighttpd through their modules. All you'll have to do is just specify file name in your header, similar to this:

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

    Link for lighttpd:

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

    0 讨论(0)
  • 2021-01-03 01:02

    You'll want to somehow authenticate them (an HTML form, HTTP basic auth, whatever), then set a session flag, which your download.php script can check. Note that this doesn't prevent people from downloading the file, then distributing it themselves.

    You should configure your web server so the real files are not directly accessible.

    It's not going to cause memory problems per se. readfile does not read the file into memory. However, using PHP will create overhead. You can eliminate some of this delay by using X-Sendfile.

    0 讨论(0)
提交回复
热议问题