我正在尝试使用PHP通过Apache的autoindex module在Apache中实现经过身份验证的文件列表。
我想象的方式是让Apache将PHP脚本作为header file运行。我已经设法让Apache为头文件正确运行PHP,它也检测到登录cookie。但似乎Apache将头文件作为单独的请求运行,这意味着如果我尝试从PHP发送重定向头,则它不会运行。
我的(简化)Apache配置:
DocumentRoot "/path/to/files_root"
Alias /~extra "/path/to/extra-data"
<Directory "/path/to/extra-data">
Options -Indexes -MultiViews +Includes
AllowOverride None
Order allow,deny
Allow from all
</Directory>
IndexOptions FancyIndexing HTMLTable SuppressHTMLPreamble
AddType text/html .php .html .htm
AddOutputFilter INCLUDES .php
AddHandler application/x-httpd-php .php
HeaderName "/~extra/HEADER.php"
我的HEADER.php文件:
<?php
if ( ! my_validate_cookie_function()) {
header('HTTP/1.1 302 Found');
header('Location: http://login.example.com/');
exit(1);
}
因此,标题不会发送到浏览器。设置Apache环境viariables似乎不起作用,因为它们在HEADER.php完成执行时就已经很久了。
Cookie本身已加密,因此需要PHP验证它。
有任何建议如何达到预期的效果?
答案 0 :(得分:3)
您应该使用index.php
标记中的以下代码将<body>
文件插入您的目录。
function fileindex($folder) {
if (!is_dir($folder)) {
return array(); //empty if not a folder
}
$list = scandir($folder);
array_shift($list); //first two values are always . & ..
array_shift($list);
return $list;
}
/* auth stuff here */
if (is_auth) {
echo "<h1> Index of ".getcwd()."</h1>\n<ul>";
echo "\n<li><a href=\"/\">Parent Directory</a>";
foreach (fileindex(".") as $i) {
echo "\n<li><a href=\"".$i."\">".htmlentities($i, ENT_QUOTES|"ENT_HTML401", "UTF-8", true)."</a></li>";
}
echo "</ul>";
}
既然你告诉我你不能使用index.php
,你应该使用Apache将目录重定向到wherever/other.php?directory=path
并从那里开始工作。
在.htaccess
中,解决方案将是
RewriteCond %{REQUEST_URI} -d
RewriteRule ^(.*)$ wherever/other.php?directory=$1 [L]
然而,最值得注意的是,您需要稍微编辑PHP代码以适应作为$_GET
参数的文件夹,而不是getcwd()
和fileindex(".")
。
答案 1 :(得分:0)
exit(1)
中的1可能是问题所在。尝试删除该号码。
我知道exit
是die
的别名,die
会将每个文本打印到客户端。
顺便说一句,我建议使用mod_rewrite
。如果cookie存在,您可以与RewriteCond
核实。如果您想查看更多内容,例如会话变量这不起作用。
答案 2 :(得分:0)
您可以使用此代码:
<Directory "/path/to/files_root">
DirectoryIndex redirected_page.php
</Directory>
答案 3 :(得分:0)
这是我最终的结果。荣誉前往Scott S,他向我暗示了解决方案。
Apache配置:
ServerName listing.example.com
# A path to a location which you wanted listed
DocumentRoot "/path/to/listed/location"
<Directory "/path/to/listed/location">
# Ignore .htaccess files
AllowOverride None
# Disable Apache's own indexing, CGI execution and Apache Includes
Options -Indexes -MultiViews -ExecCGI -Includes FollowSymLinks
Order allow,deny
Allow from all
</Directory>
<Directory "/path/to/php/listing/app">
Options -MultiViews ExecCGI
Order allow,deny
Allow from all
</Directory>
<IfModule dir_module>
# index.php should not be listed here as we will not want PHP scripts to be executed
DirectoryIndex index.html index.htm
</IfModule>
<IfModule alias_module>
# This is for CSS/JS files
Alias /~media /path/to/php/listing/app/media
</IfModule>
<IfModule xsendfile_module>
# Because the files listed might be large, we want to pass the file handling
# to Apache via XSendFile Module
# @see: https://tn123.org/mod_xsendfile/
XSendFile on
XSendFilePath "/path/to/listed/location"
</IfModule>
# Uncomment the two setting below if your listing a mounted drive
# EnableSendfile Off
# EnableMMAP Off
<IfModule rewrite_module>
RewriteEngine On
# Make sure there are trailing slashes for Directory URLs
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^(.*[^/])$ $1/ [R=302,L]
# Pass all file+dir requests to a PHP handler
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f
RewriteRule .* /path/to/php/listing/app/index.php/$0 [L]
</IfModule>
和我的PHP脚本(非常简化的版本):
<?php
if (my_authentication_check()) {
$requested_path = realpath($_SERVER['DOCUMENT_ROOT'] . $_SERVER['REQUEST_URI']);
$filename = substr($requested_path, strrpos($requested_path, DIRECTORY_SEPARATOR) + 1);
if ($requested_path) {
if (is_dir($requested_path)) {
// Show dir contents
$dir_contents = scandir($requested_path);
} else {
// Pass file download to XSendFile module
header('X-Sendfile: ' . $requested_path);
header('Content-Type: ' . my_get_file_mime($filename));
exit;
}
} else {
// display 404 error
}
} else {
// redirect to login screen, or display an error... whatever you fancy
}
我实际上使用Kohana框架和我自己的库来处理身份验证检查,显示列表等。您还必须考虑文件权限。例如。在* nix系统上,您需要检查dirs是否具有可执行权限,而在Windows上读取访问就足够了。