2

(I know this is probably a simple question to answer, but I don't know how to do it. Sorry if this has been asked before.)

What I want. I want a list of links to filse that are located on the server. The files are documents (pdf files). I understand how to use PHP to restrict access to the list of links, but one could just enter the direct link to the files in the browser and download the files. So I want to have the PHP file password protected (the list of links) and have people only enter the password once.

What I have. So far I have documents.php (found on the internet):

<?php
$username = "name";
$password = "5f4dcc3b5aa765d61d8327deb882cf99";

if ($_POST['txtUsername'] != $username || md5($_POST['txtPassword']) != $password) {
?>
<h1>Login</h1>
<form name="form" method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
    <p><label for="txtUsername">Username:</label>
    <br /><input type="text" title="Enter your Username" name="txtUsername" /></p>
    <p><label for="txtpassword">Password:</label>
    <br /><input type="password" title="Enter your password" name="txtPassword" /></p>
    <p><input type="submit" name="Submit" value="Login" /></p>
</form>
<?php
}
else {
?>
<p>Link to documents</p>
<p><a href="http://example.com/folder/file.pdf">file.pdf</a></p>
<?php
}
?>

But with this a person could just access the file from the browser with the direct link: http://example.com/folder/file.pdf.

How do I prevent a this?

(I am comfortable with PHP and javascript and basic HTML) Thanks, Thomas

DavidJCobb
  • 1,081
  • 7
  • 9
Thomas
  • 1,085
  • 5
  • 19
  • 33
  • 1
    A lot quicker to use directory access permissions, if you use Apache, lookup `.htaccess` authentication. – Orbling May 19 '11 at 23:20
  • @Orbling: I had come across the .htaccess stuff, but I don't quite understand it. Will this allow me to have a password protected page with links to the pdf files without having to enter the password again? – Thomas May 19 '11 at 23:23
  • @Thomas M: When you say, without having to enter the password again? Do you mean a permanent lack of password re-entry, or within a session (ie. until the browser is closed)? When you use basic authentication, it stores the permission until the browser is closed usually, most browsers offer to save the password for you. It allows you to setup a password file, with given users, or just a single user, and restrict access to a given directory. You can just point people straight at the file directory and use the server's directory listing capability to serve the files. – Orbling May 19 '11 at 23:32
  • @Orbling: I have never done this password protection before. What I would like is a page that contains a list of links to files (pdf files) located on the server. To see the list one needs a password (and I see how to do this with PHP). I don't know about sessions and such. I would want the files to be protected so that one can't just enter the direct link in the browser to get them. The only way to the files should be through the page with the links. Does that make sense? – Thomas May 19 '11 at 23:36
  • @Thomas M: Yes, you said that above. `.htaccess` authentication is exceptionally simple. Does your server have any control panel? If so it can probably be done from the interface without even having to write the file out. – Orbling May 19 '11 at 23:39
  • I actually don't know. It is server for a whole department. I am just a user with an account. – Thomas May 19 '11 at 23:42
  • @Orbling: So just to make sure I understand. I would just create a norman HTML files and put it together with the files in a directory /folder/ and then put the .htaccess in the folder and the .htpasswd and thats it? – Thomas May 20 '11 at 00:00
  • 1
    @Thomas M: Preferably put the `.htpasswd` file outside of the document root, you do not want people to access that. Should be no need for HTML files, unless you want to present the other files cleanly. Most webservers default to showing a listing of the files in a directory if there are no default HTML/script files. – Orbling May 20 '11 at 09:03
  • @Orbling: Thanks for your help. I made it work, and it works just as I wanted. If I could accept your comments as an answer I would. – Thomas May 20 '11 at 13:14
  • @Thomas M: NP, it is not about the score, what counts is if you are solved. – Orbling May 20 '11 at 14:14

2 Answers2

3

Mediate access to the files through php

Put the documents outside your webroot and keep a named array of the paths to them in your php file. When the client asks for a file by name (after you've authenticated them), look the file's path up in the array, and read the file from the filesystem, then output its contents back to them.

This is what readfile is designed for.

quasistoic
  • 4,657
  • 1
  • 17
  • 10
  • That makes sense I think. So would one the also restrict access to the files kept in a directory with for example .htaccess? – Thomas May 19 '11 at 23:30
  • If you put them outside of the web root, an .htaccess file would be unnecessary. – quasistoic May 19 '11 at 23:35
  • I see, I thought you meant in subfolder, but simply just have it another place on the server. So PHP can for example access files that are located in a folder "above" where the index.php file is? – Thomas May 19 '11 at 23:37
  • @quasistoic: Would an `.htaccess` solution not be vastly simpler though - four short lines in that file, and a single user/password? – Orbling May 19 '11 at 23:38
  • @Orbling: the OP said he was comfortable with php, js, and HTML. If those are the only technologies you have to work with, as is the case for a lot of folks on shared hosting, this is a good solution. For your average PHP monkey, it's a tradeoff between speed/CPU and ease of implementation. – quasistoic May 19 '11 at 23:42
  • @quasistoic: Well comfort can lead to poor choices. The Apache configuration, where available, is the standard method and is significantly less work and exceptionally simple in comparison. I did upvote you previously though, as I agree that if you are going to do it with PHP (which I sometimes do, when greater access control is required), then `readfile()` is the way. – Orbling May 19 '11 at 23:48
  • There are different reasons you might use each approach. The php approach makes it much easier to integrate with dynamic login systems, for example, and it requires no knowledge of or access to apache configurations. On the other hand, it introduces some latency and server load and won't handle very large files well. The apache configuration approach is more efficient on the server, but doesn't give you as much flexibility to integrate with more robust php/mysql access systems, and it's just not an option for some. Ultimately, for a small number of small files and few users, either is fine. – quasistoic May 19 '11 at 23:57
3

Similar to quasistoic's answer - except use your web server (eg. Apache or nginx) to provide a protected/internal URL for the PDF files (so not just a static URL within your webroot), and then use the X-Sendfile (or if on nginx the X-Accel-Redirect) header to send the file without having to stream the file through PHP.

smathy
  • 26,283
  • 5
  • 48
  • 68