5

I am trying to provide .pdf and .doc files to authorized users on a website. The user can only see the file selection page when logged in but this doesn't prevent an unauthorized user from viewing the documents if they have knowledge of the full URL.

How can I prevent unauthorized users from accessing these files?

4 Answers 4

8

the answer is quite simple, @Jonnix has posted this as I was typing but I will explain a little more for you

one put your files outside of your public HTML directory if your unable to do this look at @Andri answer for an alternative

E.G cpanel setup

user/public_html
    /public_html/download.php

user/documents/
    /documents/file.doc
    /documents/file.pdf

@dhh has posted a basic download.php php file however as your wanting to force download their things you can do like finding and supplying the correct mime type here is an extension on to his code as to the best way to 1 force download of a file, and 2 allow different file types

download.php

//check users is loged in and valid for download if not redirect them out
// YOU NEED TO ADD CODE HERE FOR THAT CHECK
// array of support file types for download script and there mimetype
$mimeTypes = array(
    'doc' => 'application/msword',
    'pdf' => 'application/pdf',
);
// set the file here (best of using a $_GET[])
$file = "../documents/file.doc";

// gets the extension of the file to be loaded for searching array above
$ext = explode('.', $file);
$ext = end($ext);

// gets the file name to send to the browser to force download of file
$fileName = explode("/", $file);
$fileName = end($fileName);

// opens the file for reading and sends headers to browser
$fp = fopen($file,"r") ;
header("Content-Type: ".$mimeTypes[$ext]);
// this header tells the browser this is a download and not to try and render if it is able to E.G images
header('Content-Disposition: attachment; filename="'.$fileName.'"');

// reads file and send the raw code to browser     
while (! feof($fp)) {
    $buff = fread($fp,4096);
    echo $buff;
}
// closes file after whe have finished reading it
fclose($fp);

P.S here is a big list of mime types if you want to add support for other files https://www.freeformatter.com/mime-types-list.html

0
3

What you can do, is provide the equivalent of a PHP proxy for the files.

Put the files outside of the webroot, then write a script that checks the user is allowed access. If not, redirect them, if they do, set the appropriate headers and output the file data.

3

You should store all downloads outside your public / user-accessable doc root (but inside your basedir, of course) and add a download script for sending the download if the user is authorized.

Here's some example of how to "send" a file for downloading it.

$file = "ireland.jpg";
$fp = fopen($file,"r") ;
header("Content-Type: image/jpeg");

while (! feof($fp)) {
    $buff = fread($fp,4096);
    print $buff;
}
1

This did the job for me: I placed a .pdf and a .htaccess file with the following code in it in a normal folder (i named it "docs") on my apache webserver.

Order Deny,Allow
Deny from all
Allow from 127.0.0.1

<Files /index.php>
    Order Allow,Deny
    Allow from all
</Files>

Then i took the code from Martin Barkers answer above, changed the filepath to "docs/sample.pdf", and pasted it into a .php file in my root directory. That's it. You can't access the file per url now, but you can download it if you run test.php.

1
  • 2
    This is a good idea if you have no support for the user directory of the web server E.G you only have access to the public_html directory and not the directory above as some free hosts provide
    – Barkermn01
    Commented Feb 19, 2013 at 12:27

Not the answer you're looking for? Browse other questions tagged or ask your own question.