Почему RewriteCond% {REQUEST_URI} мешает второму условию НЕ?

Сначала правило, которое работает:

DirectoryIndex index.php
ErrorDocument 403 /form.html

RewriteCond %{REQUEST_URI} ^/index\.php$
RewriteCond %{REQUEST_METHOD} !POST
RewriteRule . - [F,L]

Это означает http://example.com и http://example.com /index.php можно открыть только через POST .

Теперь проблема

Я добавил этот дополнительный набор правил:

RewriteCond %{REQUEST_URI} !^/index\.php$
RewriteRule . - [F,L]

Теперь я снова отправляю POST на http://example.com , но появляется такая ошибка:

Forbidden

You don't have permission to access / on this server.
Additionally, a 500 Internal Server Error error was encountered while trying to use an ErrorDocument to handle the request.

Это не имеет смысла, потому что правило НЕ должно перехватывать запросы на index.php , отправляющие 403, но хорошо, я расширил второе правило:

RewriteCond %{REQUEST_URI} !^/form\.html$
RewriteCond %{REQUEST_URI} !^/index\.php$
RewriteRule . - [F,L]

И повторная отправка POST на http://example.com не возвращает 500, но я все равно получаю 403?!

Обновление 1
Если я удалите первый набор правил, второй работает, как и ожидалось. Это означает только http://example.com , http://example.com/index. php и http://example.com/form.html доступны.

Обновление 2
Если я использую оба набора правил и отправляю POST на http: //example.com/index.php Я не получаю никаких ошибок?!

Таким образом, правила мешают, только если я отправил POST на корневой URL. Но почему?

1
задан 24 February 2017 в 03:29
1 ответ
 RewriteCond% {REQUEST_URI} ^ / index \ .php  $
RewriteCond% {REQUEST_METHOD}! POST
RewriteRule.  - [Ж, Л]
 

Предположим, что ваш DirectoryIndex установлен на index.php и у вас нет других директив, тогда это будет ваш первый блок правил, который приводит к 403 Forbidden при доступе к http://example.com/ . Вышеупомянутое разрешает прямые запросы POST только к /index.php .

Шаблон RewriteRule (одна точка) в приведенном выше примере предотвращает обработку правила вообще для запросы на http://example.com/ . Затем mod_dir инициирует внутренний подзапрос к /index.php . Обратите внимание, что этот подзапрос фактически отображается как внутренний запрос GET (это то, что устанавливается переменной сервера REQUEST_METHOD ), поэтому указанное выше условие (! POST ) выполнено успешно, и запрос в конечном итоге запрещено.

Было бы предпочтительнее канонизировать запрос и перенаправить извне (308 - постоянное перенаправление с сохранением метода запроса) любой запрос для /index.php на / . Затем вы можете сосредоточиться на сопоставлении только / и можете игнорировать подзапросы.

# Exception for error document (before other directives)
RewriteRule ^form\.html$ - [L]

# Canonicalise URL and remove "index.php" if requested
RewriteRule %{REDIRECT_STATUS} ^$
RewriteRule ^index\.php$ / [R=308,L]

# Only allow POST requests to the document root
RewriteCond %{REQUEST_METHOD} !POST
RewriteRule ^$ - [F]

(Нет необходимости во флаге L , когда используется F . L подразумевается.)

Перед тестированием убедитесь, что кеш браузера очищен. (Может быть предпочтительнее протестировать с R = 307 (временными) перенаправлениями, чтобы избежать кеширования.)

 RewriteCond% {REQUEST_URI}! ^ / Index \ .php $
RewriteRule.  - [Ж, Л]
 

Как вы предполагаете, это не противоречит приведенным выше правилам, оно соответствует чему-либо, кроме / и /index.php (при использовании в .htaccess ]). Таким образом, это запрещает доступ ко всем другим URL-адресам, независимо от метода запроса. (Как упоминалось выше, похоже, это первое правило, которое запускало 403 при доступе к http://example.com/ .) Если вы включили исключение для ваших документов об ошибках, как указано выше, тогда вы не нужно добавлять дополнительное условие.

0
ответ дан 4 December 2019 в 05:10

Теги

Похожие вопросы