htaccess файл не перенаправляет все ссылки на https и не скрывает части URL - PullRequest
1 голос
/ 20 февраля 2020

Я изменил свой htaccess-файл на своем сайте, чтобы сделать следующее:

  1. Никто не должен обращаться к базовому URL (example.com), и любой, кто пытается получить к нему доступ, должен быть перенаправлен на пример. .com / site /
  2. Принудительно https для всех ссылок, включая URL-адреса в подпапках и подпапках
  3. Скрыть / site / в отображаемом имени URL-адреса

Перенаправление HTTPS происходит, но я также могу получить доступ к http-версии любой страницы, вручную изменив https на http. Также я не могу скрыть / site / от URL, который отображается в адресной строке. И нет, у меня нет доступа к файлу vhosts.

Вот как я изменил свой файл .htaccess

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_HOST} example\.com [NC]
RewriteCond %{SERVER_PORT} 80
RewriteCond %{HTTP_HOST} ^example\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\.example\.com$ [OR]
RewriteCond %{REQUEST_URI} !^(.*)
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteRule ^(.*)$ /site/$1 [L,NC,R]
</IfModule>

Любая помощь будет принята с благодарностью.

1 Ответ

0 голосов
/ 21 февраля 2020

Таким образом, все внутренние ссылки должны иметь go - example.com/site/.*

Если вы хотите sh скрыть подкаталог /site от URL-адреса, тогда вам нужно на самом деле удалите /site сегмент URL-пути из всех ваших внутренних гиперссылок. Если в ссылке присутствует часть /site, то все ваши пользователи могут видеть ее (на странице и в строке состояния - перед тем, как щелкнуть ссылку), поэтому она вообще не «скрыта».

  1. Никто не должен иметь доступ к базовому URL (example.com), и любой, кто пытается получить к нему доступ, должен быть перенаправлен на example.com/site/
  2. Принудительно использовать https для всех ссылок, включая URL-адреса в подпапках и подпапках.
  3. Скрыть /site/ в отображаемом имени URL

№ 1 и № 3 являются противоречием. Вы не можете «перенаправить» на «/ site» (# 1) и скрыть сегмент /site URL-пути (# 3). «Перенаправление» будет выставлять подкаталог /site.

Фактически, каждый должен получить доступ к базовому URL. /site отсутствует в URL (удалив его из всех ваших внутренних гиперссылок). Затем вы внутренне переписываете все запросы, направленные на базовый URL, в подкаталог /site. Это полностью внутренний сервер - пользователь не знает об этом. Это не внешний «редирект», это внутренний «перезапись».

Следовательно, фактические процессы:

  1. Принудительно установить HTTPS для всех URL.
  2. Внутренне переписать все запросы для базового URL (например, example.com/ и example.com/foo) в подкаталог /site (например, /site/ и /site/foo соответственно).

Однако, существует необязательный шаг # 0, если это структура URL, которая изменяется - чтобы сохранить SEO и случайный доступ. И это для «перенаправления» прямых запросов на подкаталог /site обратно в root. Но это должно быть реализовано only , если вы уже удалили /site из всех ваших внутренних гиперссылок - в противном случае пользователь будет перенаправляться извне при каждом нажатии, что является "медленным" для ваших пользователей и повлияет ваш сервер. Мы также должны быть осторожны с циклами перенаправления и только перенаправлять прямые запросы от пользователя и не переписывать запросы Apache.

RewriteCond %{HTTP_HOST} example\.com [NC]
RewriteCond %{SERVER_PORT} 80
RewriteCond %{HTTP_HOST} ^example\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\.example\.com$ [OR]
RewriteCond %{REQUEST_URI} !^(.*)
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteRule ^(.*)$ /site/$1 [L,NC,R]

Если вы только имейте example.com и www.example.com (как вы указали в комментариях), тогда нет необходимости во всех проверках имени хоста (ie. HTTP_HOST) - они также дублируются, поэтому вы проверяете одно и то же здесь более одного раза.

Условие, которое проверяет %{REQUEST_URI} !^(.*), всегда будет не выполнено («не что-нибудь» всегда ложно) Только из-за условия «ИЛИ» правило может делать что угодно.

Последний RewriteRule безоговорочно «перенаправляет» все в подкаталог /site. Это откроет подкаталог /site. Вы также можете ожидать, что это создаст бесконечное перенаправление l oop, если у вас нет другого файла .htaccess в подкаталоге /site, который предотвращает это.

^(.*)$ - нет необходимости захватывать URL-путь, если вы не используете обратную ссылку в подстановке RewriteRule . В вашем перенаправлении HTTP на HTTPS это можно упростить до ^ - так как это просто необходимо для успешного выполнения каждого запроса.

Попробуйте вместо этого:

RewriteEngine On

# 1. HTTP to HTTPS redirect (same host)
RewriteCond %{SERVER_PORT} 80
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

# 2. Internally rewrite all requests to the /site subdirectory
#    Except for requests that are already for the /site subdirectory - prevent rewrite loop
RewriteRule !^site/ /site%{REQUEST_URI} [L]

Нет необходимости Оболочка <IfModule>.

И, опционально, перенаправлять внешние запросы для прямого подкаталога /site обратно на root (канонический URL). NB. Только если во всех внутренних гиперссылках подкаталог /site был удален из URL. Это будет go перед вышеуказанными директивами.

# 0. Redirect direct /site requests back to the root
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^site/(.*) https://%{HTTP_HOST}/$1 [R=301,L]

Условие, которое проверяет переменную окружения REDIRECT_STATUS, (вероятно) требуется для предотвращения перенаправления l oop, поскольку мы не хотим перенаправлять уже переписанный запрос по правилу № 2.

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

Вам нужно очистить кеш браузера перед тестированием.

Также рассмотрите возможность канонизации www subdomain.


ОБНОВЛЕНИЕ № 1: Чтобы иметь возможность Получите доступ к другим файлам в документе root или файлам вне подкаталога /site, после чего вам нужно будет добавить условие в правило № 2, чтобы исключить запросы, которые отображаются непосредственно в файлы. Например:

# 2. Internally rewrite all requests to the /site subdirectory
#    Except for requests that are already for the /site subdirectory - prevent rewrite loop
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule !^site/ /site%{REQUEST_URI} [L]

ОБНОВЛЕНИЕ № 2: Я потерял доступ к защищенному паролем каталогу в example.com/site2. Он перенаправляет на /site и говорит «файл не найден».

Вы можете сделать исключение только для этого одного подкаталога. Например, отредактируйте вышеприведенное правило следующим образом:

# 2. Internally rewrite all requests to the /site subdirectory
#    Except for requests that are already for the /site or /site2 subdirectories
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule !^(site|site2) /site%{REQUEST_URI} [L]

ИЛИ сделайте исключение для всех каталогов, кроме каталога root, который все равно необходимо переписать в /site/, чтобы Сервер вашей домашней страницы. Например:

# 2. Internally rewrite all requests to the /site subdirectory
#    Except for requests that are already for the /site subdirectory
#    Or any [sub]directory...
RewriteCond %{REQUEST_URI} ^/$ [OR]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule !^site /site%{REQUEST_URI} [L]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...