通过.htaccess和PHP保护文件

时间:2013-08-09 16:38:28

标签: php .htaccess redirect http-headers

之前可能已经讨论过了,但我找不到快速而干净的解决方案。

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)移至网络根目录之外的/media/

2 个答案:

答案 0 :(得分:3)

如果您不想更改浏览器中的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']处添加路径,具体取决于您最终找到文件的位置。

答案 1 :(得分:0)

这是我的完整解决方案。以防它对任何人都有用。谢谢@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的请求仅适用于已登录的用户。