Serving a PDF only after validating token
Is there anyway that I can "block" a user from downloading a PDF file on my server using PHP script? That is, to run a MySQL query when the file is being requested, authentic开发者_Go百科ate the user (through a cookie and MySQL query match) and only if the user is authenticated, to serve him the file.
Thanks,
Joel
The general technique is to put your downloadables outside the document root, and then allow access via a PHP script, e.g. something like this...
if ($authenticated)
{
//name of download - e.g. leaf name of file
//we strip nasties out of it...
$dl=preg_replace('/[^a-z0-9_]/i', '', $_GET['download']);
//build path to files
$file="/path/to/my/fies/$dl.pdf";
if (file_exists($file))
{
//send the file as our response, with headers to make the client
//interpret this as a saveable download...
header('Content-type: application/pdf');
header("Content-Length: ".filesize($file));
header('Content-Disposition: attachment; filename="'.$dl.'.pdf"');
readfile($file);
}
else
{
//do a 404 not found
header("HTTP/1.0 404 Not Found");
echo "Sorry, that file is not available for download";
}
}
Sure you can. Just make sure that there is no direct link to the PDF file, and use a PHP script to serve the file contents (not its location) after authentication has been performed.
To provide example code, I need to know in the form in which your PDF is stored (is it a file on disk? something else?).
Assuming the PDF is a file on disk:
if (!authentication_successful()) {
// output error message, normal PHP here
}
// Otherwise:
// Tell the browser a PDF is coming
header('Content-type: application/pdf');
// Ask it to present a save dialog, with "downloaded.pdf" as the suggested name
header('Content-Disposition: attachment; filename="downloaded.pdf"');
// Send back the PDF contents
readfile('original.pdf');
There are many ways to accomplish this, some better then others. Here is just a quick and dirty, off the top of my head method.
<?php
//Connect to your database
mysql_connect('localhost', 'user', 'pass');
mysql_select_db('database');
//Query the database
$results = mysql_query("SELECT * FROM Auth WHERE Cookie='".mysql_escape_string(@$_COOKIES['auth'])."'");
//Ensure that one and only one instance of the cookie exists in the database
if($results && mysql_num_rows($results) == 1) {
header('Content-type: application/pdf');
header('Content-length: '.filesize('my.pdf'));
if(@$_REQUEST['download'] == '1') header('Content-Disposition: attachment; filename=my.pdf'); //This forces the browser to download vs open the file
readfile('my.pdf');
exit();
}
else {
header('HTTP/1.1 403 Forbidden');
}
?>
If you wish to intercept the url /my.pdf you will need to use your web server's method for URL rewriting. Like .htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond $1 ^/my\.pdf$
RewriteRule . /index.php [L]
</IfModule>
精彩评论