在使用CPanel的godaddy托管网站上,我有一个小的PHP脚本,该脚本显示服务器上文本文件中的每一行。每行都包含一个私有的href链接,指向只有登录用户才能看到的PDF。这些链接指向服务器上同一文件夹中的各种PDF。该代码工作正常,我可以单击链接并查看每个PDF。
问题在于,每个PDF也可以通过使用直接URL查询(即website / folder / pdfname.pdf)查看。因为这些是私人PDF,所以我不希望它们公开。我尝试将文件夹的CPanel权限更改为“所有者”-但这似乎阻止了PHP脚本也打开PDF。
是否有一种方法可以允许PHP脚本访问文件夹中的PDF,但是可以防止直接URL引用?
注意:我不是特别擅长PHP或CPanel-抱歉。
代码...
$fname = "PDF-" . $user_name.".txt";
$fnum = fopen($fname,"r");
echo "<tr>";
While (($str = fgets($fnum)) !== false) {
$arr = explode("|",$str);
for ($x = 0 ; $x < count($arr); $x++) {
echo "<td>$arr[$x]</td>";
}
echo "</tr>";
}
echo "</tr>";
fclose($fnum);
文件内容...
Xyz Company|21 Jan 2018|<a href="http://website.com"> website link</a>
Xyz Company|21 Jan 2018|<a href="http://website.com"> website link</a>
Xyz Company|21 Jan 2018|<a href="http://website.com"> website link</a>
Xyz Company|21 Jan 2018|<a href="http://website.com"> website link</a>*
答案 0 :(得分:0)
除了从根目录删除文件以外,如果您正在运行apache,还可以更改.htaccess
(我确定基于Windows的系统具有与web.config
等效的功能)禁止直接访问某些文件。如果将此代码段添加到该文件,它将拒绝扩展名为.pdf
的文件:
<FilesMatch "\.(pdf)$">
Order Allow,Deny
Deny from all
</FilesMatch>
从那里,在您的应用程序内部,您可以创建某种系统来管理PDF链接,因此,如果您将真实路径存储在数据库中,并使用id作为链接,则类似于:
http://www.example.com/?file=1
或者如果您只是进行简单扫描:
<?php
# The folder that the PDFs are in
$dir = __DIR__.'/website/folder/';
# Loop over a scan of the directory (you can also use glob() here)
foreach(scandir($dir) as $file):
# If file, create a link
if(is_file($dir.$file)): ?>
<a href="?action=download&file=<?php echo $file ?>"><?php echo $file ?></a>
<?php
endif;
endforeach;
然后,如果用户尝试使用链接进行下载,则检查他们是否首先登录,如果已经登录,则通过执行类似的脚本来下载文件,然后再将其他任何内容输出到浏览器(包括空格) ):
<?php
session_start();
# First check that the user is logged in
if(empty($_SESSION['username']))
die('You must be logged in to download this document.');
# Not sure which directory you are currently in, so I will assume root
# I would do basename() here incase the user tries to add in something like:
# ../index.php and tries to download files they are not supposed to
$file = __DIR__.'/website/folder/'.basename($_GET['file']);
if(!is_file($file))
die('File does not exist.');
# Double check that the file is a pdf
elseif(strtolower(pathinfo($file, PATHINFO_EXTENSION)) != 'pdf')
die('File appears to be invalid.');
# Start download headers
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
答案 1 :(得分:0)
一个更简单和基本的例子(以及上一个答案的衍生)是使用两个单独的 PHP 文件,其中一个是在点击链接时在浏览器中评估设置的 cookie(设置为即将过期)(通过 JS 或 PHP 或其他方式设置)。如果 cookie 被正确读取,第一个 PHP 页面会导入第二个页面,该页面利用 PHP header() 重定向包含您的原始文件名用另一个名称强制下载。使用 Content Disposition 标头字段。
<a onclick="setCookie(1, 1, 2, 60)" href="php-secure-files-delivery-page.php">Download My Final PDF name.pdf</a>
<script type="text/javascript">
// set a cookie with your own time limits.
function setCookie(days, hours, minutes, seconds) { // Create cookie
var expires;
var date = new Date();
date.setTime(date.getTime()+(days*hours*minutes*seconds*1000));
expires = "; expires="+date.toGMTString();
document.cookie = "my_cookie_name"+"="+"my_cookie_value"+expires+"; path=/";
}
</script>
在链接页面上,我们包含一个带有评估 PHP 页面的超链接。在这里,我们使用 JavaScript 使用自定义函数 setCookie(days, hours, minutes, seconds)
设置 cookie,它将接收您的到期愿望。请注意,1
是最小数量。不是0
。
(php-secure-files-delivery-page.php)
<?php
// if the cookie is set correctly, load the file downloader page.
if (isset($_COOKIE['my_cookie_name'] && $_COOKIE['my_cookie_name'] === 'my_cookie_value')) {
require_once 'file-downloader.php'; // the file will force the download upon import.
} else {
die('The link expired, go to your downloads section and click on the link again.');
}
?>
在这里我们评估 cookie,显示正确的信息或 die()。使用 require_once
我们将 PHP 页面转换为当前页面。
(file-downloader.php)
<?php
// We'll be outputting a PDF
header('Content-Type: application/pdf');
// It will be downloaded as your-downloaded.pdf
header('Content-Disposition: attachment; filename="your-downloaded.pdf"');
// The PDF source is in your own specified long name
readfile('original-with-really-weird-original-name.pdf');
?>
require_once
。在服务器上的本地文件夹或指令中使用 .htaccess 文件是最好和最安全的方式。但这不能转移到其他系统上的其他应用程序。而是在您的 PDF 文件的父文件夹上使用 die()
和 index.php
页面(它们所在的位置),包括此标题重定向以消除不需要的访问:
default.php