Как запретить mod_rewrite переписывать URL-адреса более одного раза? - PullRequest
2 голосов
/ 04 октября 2011

Я хочу использовать mod_rewrite, чтобы переписать несколько удобных для человека URL-адресов для произвольных файлов в папке с именем php (которая находится в корневом веб-каталоге, поскольку mod_rewrite, очевидно, не позволит вам перезаписывать файлы вне корневого веб-каталога) .

/        --> /php/home.php
/about   --> /php/about_page.php
/contact --> /php/contact.php

Вот мои правила переписывания:

Options +FollowSymlinks
RewriteEngine On

RewriteRule ^$ php/home.php [L]
RewriteRule ^about$ php/about_page.php [L]
RewriteRule ^contact$ php/contact.php [L]

Однако я также хочу запретить пользователям доступ к файлам в этом каталоге php напрямую. Если пользователь вводит любой URL-адрес, начинающийся с /php, я хочу, чтобы он получил страницу 404.

Я попытался добавить это дополнительное правило в конце:

RewriteRule ^php php/404.php [L]

... (где 404.php - файл, который выводит 404 заголовка и сообщение «Не найдено».)

Но когда я получаю доступ к / или /about или / contact, меня всегда перенаправляют на 404. Кажется, что окончательный вариант RewriteRule применяется даже к внутренне переписанным URL-адресам (поскольку теперь все они начинаются с * 1022). *).

Я думал, что флаг [L] (на первых трех RewriteRules) должен был предотвратить дальнейшее применение правил? Я делаю что-то неправильно? (Или есть более разумный способ сделать то, что я пытаюсь сделать?)

Ответы [ 2 ]

0 голосов
/ 18 сентября 2013

У меня была похожая проблема.У меня есть система управления контентом, написанная на PHP и основанная на парадигме Model-View-Control.Самая базовая часть - mod_rewrite.Я успешно запретил доступ к файлам PHP по всему миру.Трюк имеет имя THE_REQUEST.

В чем проблема?

Модуль перезаписи перезаписывает URI.Если URI соответствует правилу, оно переписывается и другие правила применяются к новому переписанному URI.Но!Если согласованное правило заканчивается на [L], двигатель фактически не останавливается, а запускается снова.Тогда новый URI больше не соответствует правилу, оканчивающемуся на [L], продолжается и соответствует последнему.Результат?Программист начинает произносить плохие слова на странице с неожиданной ошибкой 404.Однако компьютер делает то, что вы говорите, а не делает то, что вы хотите.У меня было это в моем .htaccess файле:

RewriteEngine On
RewriteBase /
RewriteRule ^plugins/.* pluginLoader.php [L]

RewriteCond %{REQUEST_URI} \.php$
RewriteRule .* index.php [L]

Это неправильно.Даже URI, начинающиеся с plugins/, переписываются в index.php.

Решение

Правило следует применять тогда и только тогда, когда оригинал - не переписан -URI соответствует правилу.К сожалению, mod_rewrite не предоставляет никакой переменной, содержащей исходный URI, но предоставляет некоторую переменную THE_REQUEST, которая содержит первую строку заголовка HTTP-запроса.Эта переменная инвариантна.Он не изменяется, пока работает механизм перезаписи.

...
RewriteCond %{THE_REQUEST} \s.*\.php\s
RewriteRule \.php$ index.php [L]

Регулярное выражение отличается.Он применяется не только к URI, но и ко всей первой строке заголовка, что означает что-то вроде GET /script.php HTTP/1.1.Но на этот раз критическое правило применяется только в том случае, если пользователь явно запрашивает какой-либо PHP-скрипт напрямую.Переписанный URI не используется.

0 голосов
/ 04 октября 2011
Флаг

[L] следует использовать только в последнем правиле,

L - Последнее правило - здесь останавливается процесс переписывания и больше не применяются правила переписывания, и из-за этого у вас возникают проблемы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...