How to restrict image access to logged in users with PHP and .htaccess

Since I run a Utah wedding photography site, and each user gets their own online wedding gallery, I needed a way to restrict access to the user's photos to only the logged in user. I am running Apache2 and using php, so the solution involved using .htaccess to redirect all JPG requests to a PHP file which checks if the user is authorised or not. If they are not, it prints out a "please log in" JPG image, instead of the requested image.

Where to go from here

You could use PHP's getimagesize() to determine wether to send a full sized image or a thumbnail of the error message.

.htaccess to redirect requests

Download htaccess I'm pretty sure that both jpg and JPG aren't needed. I put them in initially while trying to correct a different problem.
Options -Indexes   # Don't allow index view of these folders
RewriteEngine on   # Enable rewrite

# If the requested filename ends in jpg or jpeg...
RewriteCond %{REQUEST_FILENAME} .*jpeg$|.*jpg$|.*JPEG$|.*JPG$ [NC]  # The JPG and jpg versions probably aren't needed

# Then grab the requested URL from the current directory on and stuff in in the $1 variable (first () pair maps to $1)
# Append the $1 variable as part of the query string when processing auth.php
RewriteRule (.*) http://elementsbycaroline.com/me/auth.php?img=$1 [NC,L]

PHP to restrict access

Download auth.php
<?php
    ob_start("ob_gzhandler");
if(!strip_tags($_GET['img']) || !isset($_GET['img']) || $_GET['img'] == "" ){
	// If they tried to access this file directly, send them elsewhere
	header("Location http://yourhomepageORerrorpage.com/index.php"); 
}

// We keep user authentication in a session, so we'll need access to that
session_start();

$reqpath = strip_tags($_GET['img']); // Use strip_tags to be safer


// User albums are structured like so
// ourURL.com/me/userphotos/<username>/<album>/...
// $reqpath will now have the <username>/<album>/... part
// <username> matches the username stored in the session variable
// so we get a substring from the start of $reqpath to the first /

$foundslash = strpos($reqpath,'/');  // Get the position of the first slash


if($foundslash === FALSE){  // $foundslash could return 0 or other "false" variables, use === 
	header("Location http://elementsbycaroline.com/index.php");
}

// Save their username off... 
$username = substr($reqpath,0,$foundslash);

header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Cache-Control: no-store, no-cache,must-revalidate");
header("Cache-Control: post-check=0, pre-check=0",false);
header("Pragma: no-cache");
header("Content-type: image/jpeg");

// Assume they aren't authorized unless everything lines up
$authed = FALSE;
if($_SESSION['validated'] && $_SESSION['uid'] == $username){
    $authed = TRUE; // By requireding validated and uid to be correct
		    // We prevent loggedin users from seeing other people's
		    // pictures
} 

if($authed){
    // If they're authorized, read userphotos/$PATH
    // The .htaccess file is in userphotos (since that's the top level we care to protect)
    // so the path is relative to that folder. auth.php is up one level to keep photos
    // and code as separate as possible
    @readfile("userphotos/".strip_tags($_GET['img'])); // Read and send image file
}else{
    @readfile("./path/to/jpg/to/use/if/not/authed.jpg");
}
?>

Shirts by Me

More Shirt Designs

Google
Web Stuporglue.org