通过.htaccess和PHP保护文件


protect files via .htaccess and PHP

以前可能讨论过,但我找不到一个快速干净的解决方案。

1) 我的/data/文件夹中有一堆文件:.jpg、.gif、.mp4、.pdf等。

2) 我想创建一个/data/.htaccess文件,它将捕获每个请求并将其重定向到PHP处理器,例如:

/data/filename.jpg -> /data/processor.php?file=filename.jpg

3) processor.php将执行以下操作:

3a)检查您是否有有效的$_SESSION['logged_in'] == TRUE

3b)发送相应的标题

3c)发送文件数据

理想情况下,.htaccess重定向不会更改浏览器的URL,因此只要您登录,所有当前文件请求都将保持有效。

编辑:

正如有人建议的那样,更好的方法是将我的文件保存在web根目录之外。因此,我将只保留/html/data/processor.php,并将所有媒体文件(如.jpg和.mp4)移动到web根目录之外的/media/

如果你不想在浏览器中更改URL,那么你想要的是重写URL而不是重定向。你的.htaccess文件应该是这样的:

RewriteEngine On
RewriteRule ^data/(.+) /data/processor.php?file=$1 [L]

这将导致对/data/filename.jpg的请求实际上请求/data/processor.php?file=filename.jpg,而不对浏览器中的URL执行任何操作。然后您的processor.php脚本就可以接管它了。

请记住,您必须在服务器的配置中启用mod_rewrite。

其他需要考虑的事情。您可能希望或不希望将这些文件保留在文档根目录之外,这取决于哪个更重要:安全性还是可用性。如果,htaccess部分由于任何原因失败,您希望文件在默认情况下是可访问的还是不可访问的?换句话说,在这种情况下,您是否会让用户对其访问权限产生疑问?如果是这样的话,最好将文件留在原地,因为URL只会起作用并传递用户期望的文件。如果你想在不授予访问权限方面出错,那么将文件移到文档根目录之外是很好的,这样如果没有mod_rewrite规则通过你的脚本,它们就无法访问。

/data/processor.php

以下是您的处理器的外观示例:

<?php
// Get MIME Type
    $finfo     = finfo_open( FILEINFO_MIME_TYPE );
    $mime_type = finfo_file( $finfo, $_GET['file'] );
    finfo_close( $finfo );
// Send headers
    header( "Content-Type: $mime_type" );
    header( "Content-Length: " . filesize( $_GET['file'] );
// Send file data
    readfile( $_GET['file'] );
?>

根据文件的最终位置,如果需要,请确保在$_GET['file']中包含一个路径。

这是为我制定的完整解决方案。以防万一它对任何人都有用。谢谢@Nick Coons!

HTAccess文件/html/media/.HTAccess

RewriteEngine On
RewriteCond %{REQUEST_URI} '.(png|jpe?g)$ [NC]
RewriteRule ^(.+) index.php?file=$1 [L]

处理器文件/html/media/index.php

<?php
require_once '../config/config.php';
// must be logged in
if ( ! @$_SESSION['logged_in']) exit('Access denied. You are not logged in.');
// check if file exists
$file = dirname(dirname(getcwd())) . '/media/' . @$_GET['file'];
if ( ! is_file($file)) exit('404');
// Get MIME Type
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime_type = finfo_file($finfo, $file);
finfo_close($finfo);
// Send headers
header("Content-Type: $mime_type");
header('Content-Length: ' . filesize($file));
// Send file data
readfile($file);
/* End of file */

介质文件夹/Media/

.png and .jpg files are stored here outside of the web-root

现在,对/html/media/bike.png的请求仅适用于已登录的用户。