Have an account? Sign in
Login  Register  Facebook
HTTP authentication and PHP authentication
Hi.
I'm making a members area for my site and I have it already running. I authenticate members using mysql and php and this works really well.

But now problems occurs, I would like to offer members a possibility to upload files to the systems, and those files should be available ONLY to logged in members.

I know I could store those files to a database or even in a filesystem and serve them throught php, BUT this will get very heavy for the server when members upload bigger files. Those files might be even 20MB or even bigger.

I would like to let apache serve the files, but just need to find a way to automatically do the http authentication, so users wouldn't need to log in twice. I suppose it is ok to make this http authentication behind one username and password, something like when a user logs in to the php and mysql authentication, transparently at the same time javascript etc. would do that http authentication also, every member would do the http authentication with the same credentials. Of course I wouldn't want to store those http auth credentials in a javascript file, but something ajax like solution maybe would do the trick. I'm just not sure how to do this.

I already have a php/mysql login system and now I just need to add protection to the member uploaded files. As said, serving those files with php would do the trick if I deny Apache to serve those files. But I don't want to go with that route, since it will get really heavy on the server.

I want to protect those files with Apaches build in htaccess protection, and I want to automate this http auth thing, so users doesn't have to log in twice. At first my custom member system, and after that to the htaccees protected memeber uploaded files. I'm researching about that http auth login automatisation with javascript and ajax, but I haven't had any success yet.
Started: September 18, 2011 Latest Activity: September 18, 2011 http auth javascript
3 Answers
I have been thinking a lot about the same issue. I am equally unhappy with the PHP engine running for every small resource that is served out.
But I just had an awfully interesting idea that might work.
  • Maintain a directory called /sessions somewhere on your web server.
  • Whenever a user logs in, create an empty text file with the session ID in /sessions. E.g. 123456
  • In your PHP app, serve out images like this: /sessions/123456/images/test.jpg
  • In your htaccess file, have two redirect commands.
  • One that translates /sessions/123456/images/test.jpg into /sessions/123456?filename=images/test.jpg
  • A second one that catches any calls to //sessions/(.*) and checks whether the specified file exists using the -f flag. If /sessions/123456 doesn't exist, it means the user has logged out or their session has expired. In that case, Apache sends a 403 or redirects to an error page - the resource is no longer available.
That way, we have quasi-session authentication in mod_rewrite doing just one "file exists" check!

I don't have enough routine to build the mod_rewrite statements on the fly, but they should be easy enough to write. (I'm looking hopefully in your direction @Gumbo :)

Notes and caveats:
  • Expired session files would have to be deleted quickly using a cron job, unless it's possible to check for a file's mtime in .htaccess (which may well be possible).
  • The image / resource is available to any client as long as the session exists, so no 100% protection. You could maybe work around this by adding the client IP into the equation (= the file name you create) and do an additional check for %{REMOTE_ADDR}. This is advanced .htaccess mastery but I'm quite sure it's doable.
  • Resource URLs are not static, and have to be retrieved every time on log-in, so no caching.

Posted: Go
In: September 18, 2011

It seems like you are confusing authentication (where you provide some way to login) with HTTP authentication (where you specifically use the HTTP protocol to authenticate, and the browser shows a popup to the user).

You probably want the former so you can style the login page. In that case you'll have to use PHP or some scripting langauge to check that the user is logged in. fpassthru or readfile can be good solutions for some web sites; they're fast and optimised for this type of work.

If you really want to do the file handling work in the web browser and not in PHP, one solution can be to create unique, short-lived filenames. You can for example create hard links to the file in PHP using link and then redirect the user to the temporary filename. Store the hard links in a database and remove them after a short while.

Posted: xtremex
In: September 18, 2011

I was not confusing those two things.
September 18, 2011

i think in this case you can use PHP authentication
and if you want make it available for members only its very easy you can make a php page that send the file to the browser and make it for users only using something like if(logged_in()) in example
and you can see this code for the downloading but without the authentication
$filename = $_GET['filename'];

// Modify this line to indicate the location of the files you want people to be able to download
// This path must not contain a trailing slash.  ie.  /temp/files/download
$download_path = "ficheros/";
	
// Make sure we can't download files above the current directory location.
if(eregi("\.\.", $filename)) die("I'm sorry, you may not download that file.");
$file = str_replace("..", "", $filename);
	
// Make sure we can't download .ht control files.
if(eregi("\.ht.+", $filename)) die("I'm sorry, you may not download that file.");
	
// Combine the download path and the filename to create the full path to the file.
$file = "$download_path$file";
	
// Test to ensure that the file exists.
if(!file_exists($file)) die("I'm sorry, the file doesn't seem to exist.");
	
// Extract the type of file which will be sent to the browser as a header
$type = filetype($file);

// Get a date and timestamp
$today = date("F j, Y, g:i a");
$time = time();

// Send file headers
header("Content-type: $type");
header("Content-Disposition: attachment;filename=$filename");
header("Content-Transfer-Encoding: binary");
header('Pragma: no-cache');
header('Expires: 0');
// Send the file contents.
set_time_limit(0);
readfile($file);

Posted: MacOS
In: September 18, 2011

This would be the last method to use, since it will get very heavy to send large files with php.
September 18, 2011

Storing files themselves in databases is a very bad idea. Just put them in an unaccessible directory (ie: use .htaccess to restric access) and serve them using PHP. The additional load on the server in doing so (if done correctly) is minimal.
September 18, 2011

Your Answer

xDo you want to answer this question? Please login or create an account to post your answer