4

我正在尝试通过 Apache 的autoindex 模块使用 PHP 在 Apache 中实现经过身份验证的文件列表。

我想象的方式是让 Apache 将 PHP 脚本作为头文件运行。我已经设法让 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 环境变量似乎不起作用,因为它们在 HEADER.php 完成执行的那一刻就消失了。

cookie 本身是加密的,因此需要 PHP 来验证它。

任何建议如何达到预期的效果?

4

4 回答 4

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参数而不是 agetcwd()fileindex(".")

于 2012-06-11T15:39:07.363 回答
0

1 inexit(1)可能是问题所在。尝试删除该号码。

我知道这exit是一个别名,die并将die每个文本打印给客户端。

顺便说一句,我想建议使用mod_rewrite. 您可以检查RewriteCondcookie 是否存在。如果您想检查更多例如会话变量,这将不起作用。

于 2012-06-11T13:02:56.827 回答
0

这就是我最终得到的结果。感谢Scott S,他向我暗示了解决方案。

阿帕奇配置:

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 上,读取权限就足够了。

于 2012-06-24T01:14:07.987 回答
0

您可以使用以下代码:

<Directory "/path/to/files_root">
  DirectoryIndex redirected_page.php
</Directory>
于 2012-06-11T13:08:08.577 回答