.htaccess для перезаписи URL-адресов и принудительного использования https

.htaccess для перезаписи URL-адресов и принудительного использования https

сайт: example.com

Подкаталог Joomla: example.com/joomla

Я хочу, чтобы установка Joomla по адресу example.com/joomla была (или выглядела как) корневая папка сайта, т. е. люди, посещающие example.com, перенаправляются на example.com/joompla/index.php, но по-прежнему видят example.com в адресной строке.Я также хочу использовать эту возможность, чтобы принудительно перевести все входящие соединения на HTTPS.. Мне удалось сделать одно или другое, используя скрипты, которые я нашел в Интернете, но не то и другое одновременно.

Вот что у меня есть на данный момент для .htaccess:

RewriteEngine on
RewriteBase /

# Rewrites all URLS without joomla in them
RewriteCond %{REQUEST_URI} !^/joomla/

# Rewrites all URLS with example in them
RewriteCond %{HTTP_HOST} ^(www\.)?example\.

# Rewrite all those to insert /joomla
RewriteRule ^(.*)$ /joomla/$1 [L]

# This works SOME of the time to redirect to https
Header always set Content-Security-Policy "upgrade-insecure-requests;"

# If a request tries to access /joomla directly, redirect it to its secured canonical version
RewriteCond %{THE_REQUEST} joomla/
RewriteRule ^joomla/(.*) http://example.com/$1 [R=301,L]

Это, кажется, работает некоторое время в Chrome, перенаправляя на установку Joomla и переключаясь на https, но иногда мне нужно принудительно перезагружать несколько раз, чтобы попасть туда. Это НИКОГДА не работает в Firefox, оставаясь на http в тех редких случаях, когда он вообще загружает сайт.

Я совсем новичок в .htaccess и не уверен, что разработал самое элегантное или всеобъемлющее решение вышеуказанной проблемы. Я видел другие примеры в сети, использующие RewriteCond %{HTTPS} !=onили RewriteCond %{SERVER_PORT} 80вместе с различными RewriteRuleкомандами, но я не уверен, как объединить эти команды с существующими условиями перезаписи URL, и в результате я уверен, что упускаю побочные сценарии.

Может ли кто-то с большим опытом провести меня через это? Это было бы очень ценно. Я уже несколько дней пробую варианты скриптов, найденных в сети, но так и не нашел волшебных слов.

решение1

Несколько замечаний относительно ваших существующих директив:

RewriteBase /

Хотя вы определили RewriteBase, он не используется ни в одной из ваших директив. RewriteBaseПрименяется только к относительному путизамены(вы явно использовали URL-путь относительно корня в соответствующих директивах).

# Rewrites all URLS with example in them
RewriteCond %{HTTP_HOST} ^(www\.)?example\.

Тынуждатьсяпроверить запрошенное имя хоста? Если только вы не размещаете несколько доменов (или поддоменов), к которым вы не хотите применять это правило, то этосостояниеэто излишне.

# This works SOME of the time to redirect to https
Header always set Content-Security-Policy "upgrade-insecure-requests;"

Этотникогдазапускает «перенаправление», поэтому я не уверен, что вы видите в сетевом трафике?

(На самом деле, в опубликованном вами коде нет ничего, что могло бы вызвать «перенаправление» с HTTP на HTTPS.)

Этот заголовок ответа HTTP заставляет браузер автоматически «обновлять» любые запросысвязанные ресурсы(CSS, JS, изображения, внешние ресурсы и т. д.) из первоначального ответа HTML (страницы), который в противном случае был бы через HTTP (например, потому что фактический URL содержит http://...), чтобы быть через HTTPS. Никакого фактического "перенаправления" не происходит. И ничего не происходит с первоначальным ответом HTML, который мог бы быть через обычный HTTP.

Этот заголовок не является строго необходимым, если вы реализовали перенаправление HTTP на HTTPS на всем сайте и все ваши связанные ресурсы уже являются HTTPS или используют URL-адрес относительно корня (или протокола). Но он обеспечивает хорошую страховочную сетку. Обратите внимание, однако, что любые связанные ресурсы, которые не поддерживают HTTPS, просто сломаются — браузер не выдаст пользователю предупреждения. Без этого заголовка пользователь потенциально получит предупреждение браузера о «смешанном контенте» (и связанный ресурс не будет работать).

# If a request tries to access /joomla directly, redirect it to its secured canonical version
RewriteCond %{THE_REQUEST} joomla/
RewriteRule ^joomla/(.*) http://example.com/$1 [R=301,L]

Директива RewriteCond(используемая для предотвращения цикла перенаправления в "нормальных условиях") соответствует joomla/любому месту в запрошенном URL, даже в строке запроса, что неверно и может потенциально привести к неправильным перенаправлениям, если joomla/появится в другом месте URL-пути или даже в строке запроса. Например, это приведет к циклу перенаправления, если я просто добавлю ?joomla/в конец любого URL.

Это «перенаправление» должно быть выполнено.довнутренние перезаписи. В общем случае "переадресации" должны идти перед "переписываниями", чтобы избежать перенаправления переписанного URL и раскрытия переписанного URL вашим пользователям.

Как отмечено в комментариях, это перенаправление на HTTP — противоположность тому, что вы пытаетесь сделать (и приведет к небольшой цепочке перенаправлений при реализации перенаправления с HTTP на HTTPS).

Несколько предположений:

  • Сертификат SSL устанавливается непосредственно на сервере приложений, т. е. без Cloudflare (Flexible-SSL) или другого внешнего прокси-сервера, управляющего SSL.
  • Вы не используете никаких других поддоменов. Только www.
  • Каноническое имя хоста не является www, т. е. example.com(из перенаправления в вашем вопросе).
  • В данный момент вы не реализуете HSTS, поэтому вы можете выполнить перенаправление на HTTPS и каноническое имя хоста (т. е. example.com) за одно перенаправление.
  • Сама Joomla уже настроена на исключение /joomlaподкаталога из URL-адресов. /joomlaотсутствует во внутренних ссылках, включая ссылки на статические ресурсы (CSS, JS, изображения и т. д.)
  • Вы не обслуживаете ни одного файла из корневого каталога документов.Всеперейти в /joomlaподкаталог.

Сценарий №1 — Один .htaccessфайл в корневом каталоге документов.

(Как указано в комментариях.)

.htaccessВ этом случае в подкаталоге установки ( ) нет файла "Joomla", /joomlaв котором можно было бы направить ваши URL-адреса на фронт-контроллер Joomla (т. е. index.php). В этом случае index.phpв URL-адресе должен присутствовать , и вы не можете использовать URL-адреса "SEF" Joomla.

Корневой /.htaccessфайл будет выглядеть примерно так:

RewriteEngine on

RewriteBase /joomla

# If a request tries to access /joomla directly, redirect it to its secured canonical 
RewriteCond %{THE_REQUEST} ^[A-Z]{3,7}\s/joomla
RewriteRule ^joomla(?:$|/(.*)) https://example.com/$1 [R=302,L]

# Canonicalise the hostname - ie. www to non-www and HTTPS
RewriteCond %{HTTP_HOST} ^www\.(.+?)\.?$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [R=302,L]

# Redirect remaining requests from HTTP to HTTPS
# The hostname must already be canonical at this point
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=302,L]

# Rewrite everything to the /joomla subdirectory
# Uses the value defined in the RewriteBase directive above
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule (.*) $1 [L]

# Ensure that any linked resources are requested over HTTPS
Header always set Content-Security-Policy "upgrade-insecure-requests;"

Обратите внимание, что я использовал здесь 302 (временные) перенаправления для целей тестирования. Всегда сначала тестируйте с 302 перенаправлениями и меняйте на 301 (постоянные) только после того, как убедитесь, что они работают нормально. 301 постоянно кэшируются браузером, поэтому могут затруднить тестирование.

Переменная окружения REDIRECT_STATUSиспользуется для того, чтобы гарантировать, что мы переписываем только прямые запросы, а не запросы, во многом таким же образом, как THE_REQUESTэто используется в первом правиле. REDIRECT_STATUSпуста в первоначальном запросе и установлена ​​в "200" (как в статусе ответа HTTP 200 OK) после первой успешной перезаписи. Директива RewriteRule (.*) $1 [L]может показаться немного странной на первый взгляд (кажется, что она переписывает сама себя), однако, RewriteBaseк результирующей замене добавлен префикс , поэтому на самом деле она переписывает в /joomla/<url>.

Сценарий №2 — Два .htaccessфайла: корневой каталог документа и подкаталог

Файл .htaccessв /joomlaподкаталоге будет вполне стандартным .htaccessфайлом, который поставляется с Joomla. Он направляет все запросы на фронт-контроллер Joomla (т. е. index.php) и позволяет использовать URL-адреса Joomla "SEF" (т. е. вам не нужно явно включать их index.phpв URL-адрес).

Корневой /.htaccessфайл будет выглядеть примерно так:

RewriteEngine on

RewriteBase /joomla

# Canonicalise the hostname - ie. www to non-www and HTTPS
RewriteCond %{HTTP_HOST} ^www\.(.+?)\.?$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [R=302,L]

# Redirect remaining requests from HTTP to HTTPS
# The hostname must already be canonical at this point
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=302,L]

# Rewrite everything to the /joomla subdirectory
# Uses the value defined in the RewriteBase directive above
RewriteRule (.*) $1 [L]

# Ensure that any linked resources are requested over HTTPS
Header always set Content-Security-Policy "upgrade-insecure-requests;"

Обратите внимание, что перенаправление для удаления /joomlaподкаталога из URL-адреса было удалено и должно быть помещено в /joomla/.htaccessфайл. (Оно было бы совершенно излишним, если бы его оставили здесь.)

REDIRECT_STATUSНа этот раз вам не нужна проверка env var, так как /joomla/.htaccessволяловитьзапрос после его перезаписи. (Предполагается, что наследование mod_rewrite не было включено.)

При желании директиву можно перенести в , но это необязательно, так как она в любом случае будет «унаследована » Header./joomla/.htaccess

Тогда /joomla/.htaccessфайл будет содержать что-то вроде следующего:

# JOOMLA: Set Options here

RewriteEngine on

# If a request tries to access here directly then redirect back to root
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule (.*) https://example.com/$1 [R=302,L]

# JOOMLA: Rewrite rules to block out some common exploits.
# :

# Leave the RewriteBase directive commented out - it's not required
#RewriteBase /joomla

## Begin - Joomla! core SEF Section.
RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

RewriteRule ^index\.php$ - [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [L]
## End - Joomla! core SEF Section.

Файл /joomla/.htaccessв общих чертах основан накод на сайте Joomla, однако я опустил общие элементы/комментарии и изменил «Раздел SEF» так, чтобы он соответствовал подкаталогу. (Joomla также использует менее эффективное регулярное выражение .*вместо простого ^.)

Связанный контент