Link to home
Start Free TrialLog in
Avatar of SaltyDawg
SaltyDawgFlag for United States of America

asked on

Protect files from being download unless logged in

I have a page that can only be accessed by users who are logged in. On this page are links to pdf files. The problem I have is that while the page is secure the actual files are not. A user can type in the url to the file and download the PDFs without being logged in. One option I know is to protect the directory however this will prompt the user to enter another login. Another option I thought of is to place the files in a directory not viewable by the web such as where I may have

http/www/

and www is where the site lives. Can I place the files here:

http/downloads.

If that is the case I am not sure how I can access the files from http/downloads

Is there a better way to accomplish this?
ASKER CERTIFIED SOLUTION
Avatar of gr8gonzo
gr8gonzo
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of webwyzsystems
webwyzsystems

I think you would be best to read up on, then implement HTACCESS.
This is a tried and true method to accomplish exactly what you are attempting. Since you are on Apache, everything is all ready to go.
Here's a pretty good link - read it and you should be able to complete what you want in an hour or less.
http://www.javascriptkit.com/howto/htaccess.shtml
Avatar of SaltyDawg

ASKER

using this method
readfile("../downloads/secret.pdf");

causes the browswer to open and read the file, displaying the binary data for the pdf..

How do I get the header file to work and prompt for download?

Also along with PDFs, Doc and XLS files may be there.
But doesn't HTACCESS prompt the user for a login
* remember storage the files at secure area

<?php
	/*
		check the user access right here
		if the user is not allowed to access the file, redirect to other page
	*/
 
	//download file (file path, file name)
	downloadFile("test.pdf","test.pdf");
 
	public static function downloadFile($file,$filename){
		$b = get_browser(null, true);
		if ($b['browser'] === "IE") {
	 		$filename = urlencode($filename);		
		}		
		if(file_exists($file)) {
	        header('Content-Description: File Transfer');
	        header('Content-Type: application/octet-stream');
	        header('Content-Disposition: attachment; filename="'.$filename.'"');
	        header('Content-Transfer-Encoding: binary');
	        header('Expires: 0');
	        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
	        header('Pragma: public');
	        header('Content-Length: ' . filesize($file));
	        @ flush();
	        readfile($file);
	        exit;
	    }
	}
?>

Open in new window

htaccess will prompt for login if the user is not authenticated. If the user is authenticated - everything is good. I suppose it depends on how many users you are talking about, and how your system has to scale up. HTACCESS is suited for systems that will be growing beyond 10 users. Once implemented, you don't have the overhead of checking user access on every page. The authentication header is just passed along.

There is risk in all file download handling scripts in that they are usually passed a parameter to indicate what file is to be downloaded. You need to be very careful with your coding...or saavy folks will be downloading whatever they want from your server.

How are you currently authenticating users?
while HTACCESS does protect the files, it also prompts the user for authentication which is something I don't need. The user login before they can enter that section of the site, so I do not want to prompt them again for a different login. Don't want the customers to do anything that may be redundant.
ok I did the following below code and got this.

%PDF-1.4 %âãÏÓ 45 0 obj <> endobj xref 45 36 0000000016 00000 n 0000001461 00000 n 0000001541 00000 n 0000001670 00000 n 0000001910 00000 n 0000002330 00000 n 0000002551 00000 n 0000002836 00000 n 0000002912 00000 n 0000002986 00000 n 0000005105 00000 n 0000005705 00000 n 0000006111 00000 n 0000006774 00000 n 0000006808 00000 n 0000007088 00000 n 0000007371 00000 n 0000007882 00000 n 0000008099 00000 n 0000008400 00000 n 0000008482 00000 n 0000008888 00000 n 0000009284 00000 n 0000009566 00000 n 0000009850 00000 n 0000036009 00000 n 0000038678 00000 n 0000052912 00000 n 0000072194 00000 n 0000082650 00000 n 0000094979 00000 n 0000106173 00000 n 0000227454 00000 n 0000243142 00000 n 0000252789 00000 n 0000001016 00000 n trailer <<5A09A0F78B50814F80D5B79B0E6D008A>]>> startxref 0 %%EOF 80 0 obj<>stream xÚb```"VÆÈu B  cÊr¼`Ü 0ߢi O¡îrþG*`s®¿ÍýÀ¬ ÜÎ(<¾à²ÐmZ"ÉT¡P9ä.×é0Óf8´Jâ³eñÒu"ê:z#u; G`Hå¢+~!×bÛ¢ ú¬²"Ig.&x <: T³ì}H"ÅACÜ`£N²ªRÊ=Ì!Üï(Ô±Ù3P5¸Kl>£ Æ¥¥wtt¬]âa `¹4 @: ZRM\ÁZ & `¬¹ ýè~jTdà¿ê ¦4Àö)12è778po`¿Á°!¬C"Qa!Áoûæ'Ì»¶3´6ð0è5Æ-`?ÀüâR·ô¡3¬b! c}§ÕTù¨ö2Ô3D2H>àu`ã`}Ã80Ѳ üw{@! ÄÖ@¬ÃÀÿÆH3ñ-¬7yË endstream endobj 46 0 obj<> endobj 47 0 obj<> endobj 48 0 obj<>/ColorSpace<>/Font<>/ProcSet[/PDF/Text/ImageC]/ExtGState<>>> endobj 49 0 obj<> endobj 50 0 obj<> endobj 51 0 obj<> endobj 52 0 obj<> endobj 53 0 obj<> endobj 54 0 obj<>stream H0¬WÛrÛ6}çW /©3¢q¿ô-0ÝL:Ó4êô!éCÑ6[]lR²ë·|Q¿± QtI'ãH9ÝÅ9gwA5Ê8΍ÔHcÃ9-4Á¨©2R¡hý¶ý÷3$ E »ö®³³ï(ºn;_1*rCDç}HÄ¥Ì <ýUö6»ë·¥:çv[ØIp[! ®y}ugùÇàú[C’°Æ ë.Så K¥Âð+"S¥´aƱ\jR o1ÚGF@ó5Û]'F×)ÆÔçH0ÏîÇĨ{:û0ô"'´#|hÄI8¥TO0xgö)~ÖÍ'w29AÆÞ"ôÌnü{ÛEDãwI®5°0ºí¶äqR6ÍP°¦_aÔ’wÓ/hBy\S:vz^°Â1xt<¶Ù»­"Öý¥Ú:<Æ"LSà;pW¢~îá'WÐôô&©ìBÜnáàKd¾"îq²)AÔ(ì^sÄqÜËÐ*zmÖÇСÔä6}±Óe{ö¢"èÅ;D:Ëw/.û"²u+m¹õ"fûL¢_c±jkÊbeªüʷ¤þå~ÔZä(|èwR’ôØø"0°ßuÜSaÌûYQ7ó£9]­wsÂàËÚTE{hêí5j÷žÞm[tÛÌ0Î $Qðq_¯ªú8'çx ö7ÕüÏåÏÙÜ=[Sbè~õûÙÇC½^Y!~mÕ }ÿúξ޽K}§SP:fFõÝ°t\}H4â’a#ɮҷ¼&WpDÈé)&¢ßÆ:ցs, Þ ÉAĹ'¶c:Þî£g0Y¤×6½Í¸æx­UW*ùDìƱÉAõ ’~°I(R¹BW`°ÛÕ%(º1w]’!TCÂùàlÑGÉ3åß `!¦ý"r¿{Ü5Õ2.P½]ÕÐ:Å: ®`\Æj:x %}c5Ǭ/&P¥H0áõVÊ ¦Ñ§T7ï*¨®<® ÐǼ⩍gÆñPx¨/8Ý"¿·MÓ6à aæf®s=»­abhª󤡾®Kß²ÛÝÕ|AØî»6Û_@%âSæ ’^2Jr&A\û!Zí¿]QÂ8ÁÄ ÒÇ`o8|m ßÏ.þé÷+«uê ©ÄïÈ¥æ¹Á,õ9;´0$XC:¹"ÅcDT~Ǿ »C’~=xS<{ ¬¬ÛçmÕWè!a)L. ÇóÄÜA°

(...plus more)

it seems to open the file but doesn't know how to open it. Anyone know what I can do now?
	$filename = "../media/downloads/pdf/2006_BackDrop.pdf";
	header('Content-Description: File Transfer');
	header('Content-Type: application/pdf');
	header('Content-Disposition: attachment; filename="'.$filename.'"');
	header('Content-Transfer-Encoding: binary');
	header('Expires: 0');
	header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
	header('Pragma: public');
	@ flush();
	readfile($file);
	exit;

Open in new window


	$filename = "2006_BackDrop.pdf";
	$filename = "../media/downloads/pdf/2006_BackDrop.pdf";
	header('Content-Description: File Transfer');
	header('Content-Type: application/pdf');
	header('Content-Disposition: attachment; filename="'.$filename.'"');
	header('Content-Transfer-Encoding: binary');
	header('Expires: 0');
	header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
	header('Pragma: public');
	@ flush();
	readfile($file);
	exit;

Open in new window

miscopied again
	$filename = "2006_BackDrop.pdf";
	$file = "../media/downloads/pdf/2006_BackDrop.pdf";
	header('Content-Description: File Transfer');
	header('Content-Type: application/pdf');
	header('Content-Disposition: attachment; filename="'.$filename.'"');
	header('Content-Transfer-Encoding: binary');
	header('Expires: 0');
	header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
	header('Pragma: public');
	//@ flush();
	readfile($file);
	exit;

Open in new window

ok does anyone know any script to make downloads automatically pop up from a redirection like on download.cnet.com? Also can someone confirm that doing it this way will actually hide the directory the files are actually on?

Let me add the I am not trying to make it that secure. If a savvy individual is able to find the directory, its not a real problem. My goal is just to make it where a person cannot go directly to the file and by file the page links.

if I can do it this way I have already thought of a script to move the directory location periodically
create file file.php for download


<iframe id="iFile" src="blank.html" style="display:none;"></iframe>
on user click the donwload link change the iframe url to file.php (e.g. file.php?id=123456)
the code working fine with me, or you can try following header
and check you source code file do you have are invisible char before header()
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/force-download");
header("Content-Type: application/download");
header("Content-Disposition: attachment;filename=$filename ");
header("Content-Transfer-Encoding: binary ");

Open in new window

we I use the header code I can open certain files expect application files. The browser opens the file within the browser screen and only shows the binary for that file. Like what I have shown above this is what I get when I use a pdf and the same with a .doc and .xls file.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hello ycTIN
I think this is what I am looking for. Is this using the example you have above? How is it set up?

Thanks
the code working in webserver default setting
you unzip the demo to your webserver still have same problem?
ycTIN & gr8gonzo
Ok I think I may have had some browser setting issues that cause problems with the download. I changed my setting and now your header functions are working. So I will continue to test this out and make sure I do have it right.

Thanks