Подтвердить что ты не робот

.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}

Может ли кто-нибудь помочь мне с этими условиями?

Любая помощь будет оценена.

4b9b3361

Ответ 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.