На прошлой неделе я потратил огромное количество времени, пытаясь понять это, но, что бы я ни пытался, я не могу заставить это работать. Мой веб-хостинг сказал, что у них нет никого, кто достаточно знал бы о файлах .htaccess, чтобы заставить это работать (обнадеживает, не так ли?), И компания, у которой я приобрел свою CMS, также не смогла найти решение. Я также прочитал десятки и десятки ответов здесь и на других сайтах, но я просто не могу решить свою проблему.
Вот в чем дело: Моя CMS - Invision Power Board - генерирует следующий файл .htaccess, который находится в корне веб-сайта:
<IfModule mod_rewrite.c>
Options -MultiViews
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} .*\.(jpeg|jpg|gif|png)$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . /public/404.php [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
У меня есть подкаталог, sub_dir
, который мне нужно защитить паролем, используя файл .htaccess в подкаталоге. Я устанавливаю защиту паролем через cPanel, и если файл .htaccess в корне веб-сайта отключен, он работает нормально. Однако, если файл .htaccess в корне веб-сайта не отключен, когда я перехожу к sub_dir
отображается домашняя страница. Сначала я подумал, что отображаемая домашняя страница может иметь какое-то отношение к перезаписи страницы 404, но домашняя страница все еще отображается, даже если я удалю условия перезаписи и правило для страницы 404.
Код в файле .htaccess в sub_dir
является:
AuthUserFile "/home/[user]/public_html/.htpasswd"
AuthType Basic
AuthName "subdir"
require valid-user
Как я уже упоминал ранее, защита паролем работает, когда файл .htaccess в корневом каталоге отключен. Это также работает, когда я удаляю нижние условия и правила перезаписи (строки для index.php), но удаление условий и правил перезаписи для страницы 404 ни на что не влияет.
Я испробовал десятки возможных решений, но ни одно из них не помогло. Чтобы назвать несколько, я попробовал ответить Понча ниже:
RewriteCond %{REQUEST_URI} !^sub_dir
Я тоже пробовал это:
RewriteRule ^/sub_dir - [L]
А также многие, многие другие вещи, о которых я сейчас даже не помню. Дело в том, что пока ничего не работает. Я также пробовал все возможные комбинации в отношении ведущей и следующей косой черты.
На моем сервере работает Apache 2.2.22.
Я серьезно нахожусь здесь в своем уме. Пожалуйста помоги.
Казалось бы, вы уже пробовали это, это наиболее очевидный ответ (как указал Понча), и он, вероятно, наиболее вероятно появится в руководстве / руководстве по mod_rewrite. Исключая каталог с помощью RewriteCond
, отмечая, что условие совпадает с %{REQUEST_URI}
, который начинается с /
":
<IfModule mod_rewrite.c>
Options -MultiViews
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} !^/sub_dir
RewriteCond %{REQUEST_FILENAME} .*\.(jpeg|jpg|gif|png)$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . /public/404.php [L]
RewriteCond %{REQUEST_URI} !^/sub_dir
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
РЕДАКТИРОВАТЬ:
Глядя на то, что вы пробовали, это тоже неправильно. Вам не нужна ведущая косая черта в матче RewriteRule
когда он находится в файле htaccess:
<IfModule mod_rewrite.c>
Options -MultiViews
RewriteEngine On
RewriteRule ^sub_dir - [L]
RewriteBase /
RewriteCond %{REQUEST_FILENAME} .*\.(jpeg|jpg|gif|png)$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . /public/404.php [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
Приведенные выше решения не работают, потому что они не решают фундаментальную проблему, заключающуюся в том, что подпапка, которая должна быть исключена из правил, защищена паролем.
Когда первоначальный доступ отклоняется Apache и отображается диалоговое окно входа в систему, правила перезаписи срабатывают, но не могут перенаправить клиента к доступному файлу, поэтому возникает ошибка 404. Чтобы решить эту проблему, нам нужно предоставить «фиктивный» файл, к которому клиент может быть направлен, если первоначальная попытка доступа не удалась.
ErrorDocument 401 /failed_auth.html
RewriteCond %{REQUEST_URI} ^/pwd-protected-sub-folder/(.*)$ [OR]
RewriteCond %{REQUEST_URI} ^/failed_auth.html$
RewriteRule ^.*$ - [L]
Первое уведомление:
AuthUserFile "/home/[user]/public_html/.htpasswd"
Похоже, ваш файл .htpasswd находится в общедоступном месте (public_html). Это проблема безопасности, вы должны поместить этот файл туда, где пользователь apache может его прочитать (проверьте права на каталог и файлы), но, конечно, не в место под DocumentRoot. Никто не может напрямую запрашивать файл .htpasswd, это файл только на стороне сервера. Но это не связано с твоей проблемой.
Ваша основная проблема в том, что вы не ответили на вопросы @Jon Lin и @mootinator. Какие файлы вы пытаетесь запросить в sub_dir, есть ли там какие-то файлы html, другой файл index.php? Следует ли разрешить список каталогов в этом каталоге? Как вы делаете свои тесты.
Когда делается запрос к sub_dir, родительский .htaccess применяется по умолчанию (пытается перенаправить каждый запрос, который вы можете себе представить, на boostrapper index.php, за исключением отсутствующих файлов изображений и за исключением существующих каталогов или файлов). Поэтому, запрашивая реальный файл в sub_dir, у вас не должно возникнуть проблем с этими правилами.. Хороший способ проверить это - прокомментировать Rules в корневом файле .htaccess.
Вы сказали, что провели несколько тестов без корневого файла .htaccess, и это сработало. Так что, возможно, удаление Options -MultiViews
что сделало ваши тесты в порядке. MultiViews является частью переговоров по содержанию и представляет собой очень волшебное слово с очень странным поведением, поэтому допустим, например, вы запрашиваете subd_dir/foo
в ваших тестах MultiViews может найти файл sub_dir/FoO.html
и служить ему. Удалите MultiViews, и ваши тесты больше не будут работать (возможно). Предложения @Mootinator по проблемам с символическими ссылками также могут быть действительными, и у вас также может быть что-то в протестированных файлах, перенаправляющее на URL-адрес, пойманный первым правилом, странным вещам нет конца. Но точно "не работает" недостаточно, что это "это"?
Как я уже сказал, вам нужно предоставить нам больше информации. И дайте всем остальным читателям (даже в будущем) достаточно элементов, чтобы увидеть, может ли ваша проблема быть связана с их проблемами. Цель состоит не в том, чтобы нанять экспертов для работы непосредственно на вашем сервере, а в том, чтобы получить достоверные ответы на действительные и подробные проблемы.
Как насчет того, чтобы попробовать просто сделать это в своем sub_dir
.htaccess, чтобы запретить modrewrite распространяться на ваш sub_dir
:
## turn off rewrite engine
RewriteEngine Off
## now do your auth stuff
AuthUserFile "/home/[user]/public_html/.htpasswd"
AuthType Basic
AuthName "subdir"
require valid-user
и если вам действительно нужны правила перезаписи для работы внутри sub_dir, тогда делайте их специально в этом файле .htaccess, чтобы не было путаницы. Как только вы запускаете RewriteEngine On / Off, правила из родительской папки не применяются напрямую. Сначала они считываются из этой папки, а затем из корня.
Это правило перенаправляет на домашнюю страницу, если запрошенный путь не является существующим файлом или каталогом.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
Очевидно, что поскольку вас перенаправляют на домашнюю страницу, сервер считает, что либо sub_dir
каталог не существует, или запрос на sub_dir
перенаправляется на то, чего не существует.
Первое, что нужно проверить в этом сценарии, - это, конечно, sub_dir
является фактическим каталогом, имея в виду, что в зависимости от вашего имени каталога будет чувствительный к регистру в большинстве случаев, когда запущен Apache, а также имея в виду, что символическая ссылка не обязательно рассматривается так же, как каталог.
Добавить еще RewriteCond
исключить желаемое sub_dir
(к обоим правилам):
RewriteCond %{REQUEST_URI} !^sub_dir
Добавляем это в надежде, что это поможет кому-то другому. Я думаю, что @Mike L был на правильном пути. У меня была аналогичная ситуация (подкаталог htaccess, защищенный паролем, с правилами перезаписи в корневом htaccess, который мне все еще нужен для основного сайта). В конце концов, решением для меня было просто добавить это в корневой файл .htaccess.
ErrorDocument 401 "Unauthorised"
Конечно, вам все равно нужно будет добавить соответствующие правила, чтобы разрешить доступ к подкаталогу, но запрос пароля, который не отображался, был исправлен с использованием вышеуказанного. Надеюсь, поможет!
Для сайта, использующего простой общий хостинг на основе cPanel (Apache 2.2), я решил, похоже, ту же проблему, добавив файл с именем «401.shtml» в корень документа (public_html). Простое существование файла, даже без директивы ErrorDocument 401 в .htaccess, решило проблему.