Надежное решение:
# If not on www., redirect to www. on SSL
RewriteCond %{REMOTE_ADDR} !127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}
RewriteCond %{HTTP_HOST} !^www
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
# If not on SSL(ish), redirect to SSL
RewriteCond %{SERVER_PORT} !^443$
RewriteCond %{REMOTE_ADDR} !127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
Давайте разберем его.
Если запрашивающий клиент НЕ находится на зарезервированном локальном IP-адресе
RewriteCond %{REMOTE_ADDR} !127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}
Как правило,при доступе к локально размещенному веб-сайту IP-адрес клиента составляет 127.0.0.1
.Время от времени это 127.0.1.0
.Но весь диапазон 127.x.x.x
зарезервирован для локальных, поэтому я проверяю их всех, на случай, если у вас будет веселая настройка.
Это безопаснее, чем проверка на localhost
или проверка наналичие .
- оно также позволяет вам редактировать файл /etc/hosts
, указав www.myDomain.com
на вашем локальном хосте для более реалистичного тестирования.Или, если вы похожи на меня, у вас есть доменная номенклатура, например nathan.dev.mydomain.com
или mydomain.com.dev
.
Проверка на "www."
RewriteCond %{HTTP_HOST} !^www\.
Если домен не 't (!
= не) начинается с (^
= начинается с) www.
...
Порт 443 против переменной среды HTTPS
RewriteCond %{SERVER_PORT} !^443$
Использование порта 443это более безопасная проверка, поскольку переменная среды HTTPS не может быть гарантирована при работе с серверами с балансировкой нагрузки.
Действительное правило
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
Это заставит все использовать "www."эквивалент этого домена .Например, mydomain.com становится www.mydomain.com;mydomain.de становится www.mydomain.de.
В качестве альтернативы вы можете использовать следующее правило, которое заставляет каждый домен перенаправлять на www.
, а также на .com
:
RewriteRule ^(.*)$ https://www.myDomain.com/$1 [R=301,L]
Два блока условий / правил, а не один.
Используя два блока, вы можете иметь немного больше ясности относительно того, что именно происходит.Кроме того, запись этого как одного блока просто не будет работать, если необходимо разрешить использование любого TLD.Вы можете объединить их в один блок, если вы использовали альтернативное правило выше.Альтернатива с одним блоком будет выглядеть следующим образом (обратите внимание на добавление [OR]
):
RewriteCond %{REMOTE_ADDR} !127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}
RewriteCond %{HTTP_HOST} !^www [OR]
RewriteCond %{SERVER_PORT} !^443$
RewriteRule ^(.*)$ https://www.myDomain.com/$1 [R=301,L]
Стоит также отметить, что решение с двумя блоками иногда приводит к двум перенаправлениям, , но если вы оставите его в точном порядке, вы уменьшите количество перенаправлений.
Пример: при текущем порядке правил, если клиент запросил http://mydomain.com
, будет применен первый блок (не существует www.
)) и перенаправит на https://www.mydomain.com
.Однако, если вы перевернули заказ, сервер сначала обнаружит отсутствие SSL, а клиент будет перенаправлен на https://mydomain.com
, , затем , сервер обнаружит отсутствие www.
и послужит дополнительнымперенаправить на https://www.mydomain.com
.tl; dr: не меняйте порядок.:)
Счастливого взлома!