web-dev-qa-db-ja.com

HTTP_Hostを使用する.htaccessには、HTTPSを強制するときに余分なリダイレクトが1つあります

.htaccessファイルでこれらの行を使用すると、すべてが正常に機能します。

RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://example.com%{REQUEST_URI} [L,R=301]

enter image description here

次に、URLに手動でドメインを記述せずに機能するようにし、代わりに次の行を試しました。

RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_Host}%{REQUEST_URI} [L,R=301] 

しかし、httpsなしでwwwから到達した場合、追加のリダイレクトがあります:

enter image description here

理由がわかりません。ドメインを{HTTP_Host}に置き換えただけです。それを行うと、http://www.example.comからhttp://example.comにリダイレクトされ(メインドメインなので)、http://example.comからhttps://example.comにリダイレクトされます。

次の行を追加しても、RewriteCond %{HTTP_Host} !^www\. [NC]は何も変更しません。

なぜそれがそのように振る舞うのですか?.htaccessファイルを手動でURLを記述してhttp://www.example.comhttps://example.comに直接リダイレクトする必要がないように修正するにはどうすればよいですか?

3
imlost

ホスト名からwww.を常に削除する場合は、ドメイン名を含むルールの最初のセットを使用する必要があります。これは、{HTTP_Host}変数にサブドメインを含む完全なホスト名が含まれているためです。したがって、http://www.example.comでサイトにアクセスすると、HTTP_Hostwww.example.comになります。リダイレクトでその変数を使用すると、www.が含まれます。

その書き換えルールでドメイン名をハードコーディングすることに本当に反対する場合は、HTTP_HostからSERVER_NAMEに切り替えることができます。サーバー名変数は、UseCanonicalName onがオンになっている場合にのみ、仮想ホスト構成で指定された優先ホスト名にすることができます。 PHPのHTTP_HostとSERVER_NAMEの違いは何ですか? を参照してください。仮想ホストの構成は次のようにする必要があります。

<VirtualHost *>
    ServerName example.com
    UseCanonicalName on
    ServerAlias www.example.com
    ...
</VirtualHost>

仮想ホストディレクティブを細かく制御できない場合があります。 cPanalやWHMなどの多くのホスティングパッケージが設定を作成し、変更を許可しません。書き換えルールでは、ハードコーディングされたドメイン名を使用することをお勧めします。これは、簡単に実行でき、機能するためです。

1

tl; drコードベースにはリダイレクトしているものがあります。質問で投稿したディレクティブは、表示されている出力を(完全に)説明していません。実際、.htaccessファイルから投稿したディレクティブはまったく処理されない場合もあります...

(この答えは、実際に@Stephenの答えに加えて、あなたが見ている結果を説明(または質問)しようと試みたものです。)

.htaccessファイルでこれらの行を使用すると、すべてが正常に機能します。

RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://example.com%{REQUEST_URI} [L,R=301]

「すべてがうまく機能します」-これらのディレクティブは、あなたが言及した最初の2つのシナリオ(つまりfrom HTTP)に対してのみ責任があります。

  • http://www.example.comからhttps://example.com
  • http://example.comからhttps://example.com

ただし、これらのディレクティブは、あなたが示唆するように、https://www(3番目のシナリオ)からリダイレクトしません。 wwwサブドメインを正規化しません。 他の何かはこのリダイレクトを実行しています。

ドメインを{HTTP_Host}に置き換えました。これを行うと、http://www.example.comからhttp://example.comにリダイレクトされ(メインドメインであるため)、http://example.comからhttps://example.comにリダイレクトされます。

投稿したディレクティブを指定します。これは不可能です!ディレクティブはhttpsにのみリダイレクトするため、「何か他のもの」がhttpへの最初のリダイレクトをトリガーする必要があります。 (しかし、あなたの.htaccessリダイレクトの前には何も起こらないはずです-メインサーバーの設定、またはおそらく別の.htaccessファイルの場合を除きますが、そのようなものは変更されていないと思いますか?)

cachedリダイレクトが表示されている可能性がありますが、「ドメインを{HTTP_Host}に置き換えただけです」と言うので、その種のルールはキャッシュから除外されます。

次の行を追加しても、RewriteCond %{HTTP_Host} !^www\. [NC]は何も変更しません。

さて、それは間違いなく上記で見た追加のリダイレクトを変更したはずです(RewriteRuleディレクティブの前にどこかに追加したと仮定します)。したがって、これが何もしなかった場合、「何か他のもの」がこれらのリダイレクトを実行しており、おそらくディレクティブがまったく処理されていないことをさらに示唆しています!

ただし、この追加のリダイレクトは、「ドメインを{HTTP_Host}に置き換えた」後にのみ開始することを提案しています。これは不可能と思われます。したがって、他の何かも変更されている必要があります


これらのいくつかは、.htaccessファイルでこれらのディレクティブを間違った順序で配置したことで説明できます。たとえば、WordPress(またはfront-controllerパターンを使用する別のCMS)を使用していて、リダイレクトをファイルの最後に配置した場合、ほとんどのページで要求されます。処理されません。ただし、設定によっては、ホームページと静的リソースで処理される場合があります。

この性質のリダイレクトは、.htaccessの最初に行く必要があります。

また、mod_alias Redirect(またはRedirectMatch)ディレクティブとmod_rewrite RewriteRuleを混在させないでください。これにより、予期しない競合が発生する可能性があります。


... .htaccessファイルを手動でURLを記述してhttp://www.example.comhttps://example.comに直接リダイレクトする必要がないように修正するにはどうすればよいですか?

Aside:実装しようとしている場合 HSTS その後、皮肉なことに、2つのステップでリダイレクトする必要があります(上記のHTTP_Hostを使用)。最初のリダイレクトはHTTPS 同じホスト上に進み、オプションでHTTPSの標準的なwww/non-wwwリダイレクトが続きます。

単一のリダイレクトでリダイレクトするために、@ Stephenが答えで示唆しているように、必ずしもserver-configを使用する必要はありません(可能性はありますが)。ただし、サーバー構成にアクセスできる場合は、mod_alias Redirectおよび<VirtualHost>コンテナー(より速く、おそらく「よりシンプル」)を使用してこれを行うより良い方法があります。mod_rewriteはまったく必要ありません。

ただし、次のようなものを使用して、.htaccessでこれを単一のリダイレクト(HTTPからHTTPS、およびwwwからwww以外)として実装できます。

RewriteEngine On

RewriteCond %{HTTPS} !on [OR]
RewriteCond %{HTTP_Host} ^www\. [NC]
RewriteCond %{HTTP_Host} ^(?:www\.)?(.+)\.?$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [R=302,L]

上記は、HTTPSではないすべてのリクエストについてまたはリクエストされたホスト名www.を開始し、https://<hostname-less-www-prefix>/<URL-path>にリダイレクトします。これにより、FQDNの場合にオプションの末尾のドットも削除されます。 3番目のconditionは、(オプションの)www.プレフィックスよりも少ないホスト名をキャプチャするために必要です。これは、%1後方参照にキャプチャされます。

上記は302(一時)リダイレクトであることに注意してください。テストを実行し、正常に動作していることを確認した後にのみ、これを301(永続)リダイレクトに変更します(テストの曇りを防ぐため)。

このようにディレクティブを一般化することは、システム全体で常に最良の(または最も信頼性の高い)ソリューションとは限りません。

1
MrWhite