サブディレクトリにインストールしたワードプレスで、httpからhttpsに301リダイレクトする際に、リダイレクト先のURLが正しくないケースがありました。
当サイトの場合だと、
このようになってしまう現象です。
これは、サブディレクトリにインストールしたワードプレスのプラグイン「Really Simple SSL」が.htaccessに挿入したリダイレクトルールが原因でした。
この記事では、この現象が起きる理由や、解決方法についてお伝えします。
目次
原因は「Really Simple SSL」のリライトルール
ワードプレスのプラグイン「Really Simple SSL」は、.htaccessに以下のリダイレクトルールを挿入する機能があります。
# BEGIN rlrssslReallySimpleSSL rsssl_version[5.2.0]
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
</IfModule>
# END rlrssslReallySimpleSSL
サブディレクトリにインストールしたワードプレスで、この内容を.htaccessに記載すると、正しくリダイレクトが機能しません。
実際には以下のようにリダイレクトされてしまいます。
この現象が起きる原因には様々な技術的な要因が関わっています。
ひとつずつ解説していきますが、解決方法が先に知りたい方は、「修正方法」の見出しまで読み飛ばしてください。
サブディレクトリではサブディレクトリの.htaccess設定が優先
突然話が逸れるのですが、まず、.htaccessの設定がルートディレクトリとサブディレクトリで競合する場合、サブディレクトリのサイトではサブディレクトリの.htaccessの設定が優先されます。
文章で書くと意味不明ですが、詳細はこちらの記事を参考にしてください。
当サイトの場合は、ルートディレクトリとサブディレクトリの両方のワードプレスに「Really Simple SSL」をインストールしていました。
そのため、どちらの.htaccessにも同じリライトルールが挿入されていますが、実際に適応されていたのはサブディレクトリの.htaccessになります。
.htaccessのリライトルールの意味
.htaccessに記載されたリライトルールの意味を、簡潔にお伝えします。
# BEGIN rlrssslReallySimpleSSL rsssl_version[5.2.0]
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
</IfModule>
# END rlrssslReallySimpleSSL
RewriteEngine on | これからリダイレクトの設定を書くよ | ||
---|---|---|---|
RewriteCond | これから判定条件を書くよ | ||
%{HTTP:X-Forwarded-Proto} | 通信プロトコルが | ||
!https | httpsじゃなかったら | ||
RewriteRule | これからリダイレクト先を指示するよ | ||
^(.*)$ | アクセスしようとしてるURLのパスの部分を変数$に入れるよ | ||
https://%{HTTP_HOST}/$1 | リダイレクト先は、 https:://にHTTP_HOSTと$(パス名)をくっつけたものだよ |
||
[R=301,L] | リダイレクト方式は301で、もしこの条件にマッチしたら以降のルールは読まないよ |
リダイレクト処理が正しく行われない理由
先ほどのリダイレクト設定において、重要なのは
https://%{HTTP_HOST}/$1
の部分です。
HTTP_HOSTは、ドメイン名になります。
つまり、当サイトの場合はbluegoat.jpとなります。
$1はURLのパスになるのですが、サブディレクトリの場合はサブディレクトリ名以降がパスになります。
つまり、HTTP通信で
bluegoat.jp/blog/sub-dir-redirect/ にアクセスする場合、
blog/に設置された.htaccessから見ると、
/sub-dir-redirect/
がパスになります。
すると、https://%{HTTP_HOST}/$1の内容は
となってしまい、サブディレクトリ/blogの記載が抜けてしまいます。
修正方法は2パターンあり
修正方法は2パターンあります。
どちらでも正しくリダイレクトしますので、お好きな方を選んでください。
パターン①:リライトルールにサブディレクトリのパスを追加
サブディレクトリ名が抜けているのが原因なので、以下のように追加すれば正しく動作します。
当サイトはルートドメイン直下のディレクトリ/blogにワードプレスをインストールしているので、以下のように記載すれば直りました。
変更前:RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
変更後:RewriteRule ^(.*)$ https://%{HTTP_HOST}/blog/$1 [R=301,L]
ご自身のサイトの場合に置き換えて、ディレクトリ名を入れてみてください。
注意点としては、編集する.htaccessはサブディレクトリのファイルです。
ルートディレクトリの.htaccessは編集しないようにしてください。
パターン②:サブディレクトリのリライトルールを削除する
トップドメインにて「Really Simple SSL」のリライトルールが記載されている場合は、トップドメインのリライトルールが、サブディレクトリでも動作します。
サブディレクトリとトップの.htaccessと競合してしまっているのが問題なので、サブディレクトリのリライトルールのみ削除すれば、正しいURLにリダイレクトがかかります。
(通常のWebサイトでも全てのURLでhttp → httpsのリダイレクトがかかるのと同じ原理です。)
プラグイン「Really Simple SSL」では、ボタン1つでリライトルールを削除することができるので、「301 .htaccess 転送を有効化」のボタンをOFFにしましょう。
すると、自動的にリライトルールが.htaccessから削除されます。
2回目以降は正しくhttpsでつながる理由
「httpで接続したら、1回目は正しいURLにリダイレクトしなかったけど、2回目以降は正しいURLにリダイレクトするようになった」というケースもあると思います。
その現象が起きる理由は、通信ヘッダにHSTSというセキュリティヘッダーが付与される設定にしていることです。
HSTSセキュリティヘッダが付与される設定にしていると、2回目以降の通信は全てhttpsで行うようにブラウザに記憶させます。
全く記憶のない状態で通信するには、 Chromeのシークレットモードでサイトにアクセスしてみてください。
最初の1回目の通信では、セキュリティヘッダが付与されていないめリライトルールが適応され、正しくないURLに転送されるはずです。