.htaccess RewriteCond, где URI не содержит домен
Я просмотрел Google и StackOverflow для ответа на этот вопрос, но тот факт, что я мало что знаю о .htaccess, не помогает мне решить, какие правильные ответы для моей ситуации есть, поэтому я прошу здесь.
Моя ситуация в том, что у меня есть несколько сайтов, которые используют тот же физический каталог, что и их корень на сервере.
Все работает нормально, но я хотел убедиться, что каждый сайт не может получить доступ к изображениям других пользователей и т.д. из браузера, если они не находятся в правильном домене.
В настоящее время у меня есть такая файловая структура, как это:
/resources/{resource}/{full_domain_name}
Итак, например, www.domain.co.uk
будет иметь такую структуру:
http://www.domain.co.uk/resources/images/www.domain.co.uk/some_image.jpg
Но если www.domain_2.co.uk
существует, используя один и тот же физический каталог для корня сайта, тогда они могут просматривать другие ресурсы домена из своего собственного домена, например:
http://www.domain_2.co.uk/resources/images/www.domain.co.uk/some_image.jpg
Это не является серьезной проблемой, поскольку в этих каталогах нет никакой конфиденциальной информации, но это скорее раздражение, и я бы предпочел, чтобы пользователи не смогли это сделать (не то, что у кого-то на самом деле до сих пор).
Я попытался поместить файл .htaccess в каталог /resources, но я застрял с регулярными выражениями и т.д.
Я в основном хочу убедиться, что URI содержит текущее имя домена, иначе перенаправляется на страницу ошибки 403.
Вот что я придумал:
RewriteCond %{REQUEST_URI} !^(/resources/[^/]*/%{HTTP_HOST})(.*)$
RewriteRule ^(.*)$ /error/403.php
Причина, по которой я вставил бит [^/]
, состоит в том, что существует несколько папок, например:
/resources/images/{full_domain_name}
/resources/scripts/{full_domain_name}
/resources/stylesheets/{full_domain_name}
Может ли кто-нибудь помочь мне с этими условиями?
Любая помощь будет оценена.
Ответы
Ответ 1
Это потрясающий вопрос, и если бы я мог бы удержать 10+ раз. Я отправляю свой ответ, даже несмотря на то, что у вас есть принятый ответ здесь, поскольку мне действительно нужно было копать все ресурсы Apache, чтобы придумать ответ. Вот правило, которое вам понадобится для этой проблемы:
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST}:%{REQUEST_URI} !^([^:]+):/resources/[^/]+/\1/.+ [NC]
RewriteRule ^resources/[^/]+/[^/]+/.+ - [F,NC,NE]
PS: Поскольку мы не можем использовать переменные %
на RHS в качестве обратной ссылки, я использую специальную переменную regex back-reference \1
в RewriteCond
здесь.
Ответ 2
Это условие недостаточно:
RewriteCond %{REQUEUST_URI} !^(/resources/[^/]*/%{HTTP_HOST})(.*)$
Потому что, если я запрашиваю все, что не начинается с /resources/
, я получу страницу ошибки 403.php. То, что вы действительно хотите, это примерно так:
RewriteCond %{REQUEST_URI} ^/resources/[^/]+/([^/]+)/
RewriteCond %{HTTP_HOST} !%1
Или
RewriteCond %{REQUEST_URI} ^/resources/[^/]+/([^/]+)/
RewriteCond %{REQUEST_URI} !^/resources/[^/]+/%{HTTP_HOST}/
Если первое условие проверяет, что запрос предназначен для ресурса, тогда вторая проверка хоста. ОДНАКО, ни одна из них не будет работать, потому что директива mod_rewrite RewriteCond
не разрешает переменные % или обратные ссылки в правой части условия, а только левые. Точно так же вы не можете этого сделать:
RewriteCond %{REQUEST_URI} ^/resources/[^/]+/([^/]+)/
RewriteRule !^/resources/[^/]+/%{HTTP_HOST}/ /error/403.php
Поскольку выражение RewriteRule не может иметь в нем переменных, так как это регулярное выражение, и оно буквально ожидает %{HTTP_HOST}
вместо того, чтобы заменить его на Host, заданный в запросе. Итак, в заключение, нет, вы не можете сделать это с mod_rewrite условия таким образом.
Что-то, что вы можете попробовать, если у вас есть доступ к конфигурации сервера или конфигурации vhost, является создание RewriteMap и передача как в %{REQUEST_URI}
и %{HTTP_HOST}
. Поэтому, если ваша карта называется check_host
, ваше правило может выглядеть примерно так:
RewriteRule ^resources/[^/]+/([^/]+)/ ${check_host:%{HTTP_HOST}_%{REQUEST_URI}}
И вашему script просто нужно будет разобрать вход, разделить его от первого _
, проанализировать URI запроса и убедиться, что хост совпадает с HTTP_HOST. Если это то же самое, выведите один и тот же запрос URI, иначе выведите URI ошибки. Если у вас нет доступа к конфигурации сервера или vhost, я думаю, вам не повезло. RewriteMap не может быть определен в файле htaccess.