2012-06-11 3 views
4

Я пытаюсь достичь аутентифицированного списка файлов в Apache, используя PHP через Apache autoindex module.Как перенаправить страницу Apache «Index of ...»?

Как я мог предположить, что Apache запускает PHP-скрипт как header file. Мне удалось заставить Apache правильно запускать PHP для файла заголовка, и он также отлично определяет файлы cookie для входа. Но кажется, что Apache запускает заголовочный файл как отдельный запрос, что означает, что если я попытаюсь отправить заголовок перенаправления с PHP, он не будет запущен.

My (упрощенный) 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.

Любые предложения по достижению желаемого эффекта?

+0

Я бы предположил, что было бы проще иметь файл 'index.php' в каталоге и иметь список файлов там (если они аутентифицированы). Вы хотите, чтобы я ответил этим методом? –

+0

@ScottS Пожалуйста, ответьте своим решением. К сожалению, в данный момент мне не удается поместить файл index.php в каталог, поскольку он доступен только для чтения, но в других случаях он кажется разумным решением (если вы все еще используете Apache для обработки файлов, а не PHP). –

ответ

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 достаточно.

0

1 в exit(1) возможно проблема. Попробуйте удалить это число.

Я знаю, что exit является псевдонимом для die и die печатает каждый текст клиенту.

Кстати, я хотел бы предложить использовать mod_rewrite. Вы можете проверить с RewriteCond, если файл cookie существует. Если вы хотите проверить больше, например. переменные сеанса это не сработает.

+0

Невзирая на то, что даже если я полностью удаляю 'exit()', это не сработает. Я попробовал просто добавить заголовок foo, например 'header ('X-Foo: Bar')', но он не отправляется в браузер. –

+0

Вы действительно уверены, что используете PHP-файл? – rekire

+0

Да, но, как я уже упоминал, Apache, похоже, выполняет отдельный внутренний запрос для HEADER.php и использует только свой вывод, который объединен с листингом файла, сгенерированным внутри и выходом FOOTER.php (из коэффициента усиления отдельный запрос) –

0

Вы можете использовать этот код:

<Directory "/path/to/files_root"> 
    DirectoryIndex redirected_page.php 
</Directory> 
+0

Это не учитывает валидацию файлов cookie. –

+0

Это не так. Но по соображениям безопасности вы должны проверить свой файл cookie во всех разделах своего сайта, поэтому, если вы выполняете правильную проверку, вам не нужно беспокоиться о проверке Apache в DirectoryIndex. Этот вариант работает так хорошо для меня, начиная с 2 лет назад. –

+0

@VicAbreu Как это работает? Что такое redirected_page.php в этом случае? –

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(".").

Смежные вопросы