WordPressで作成した当サイトをSSLに対応させました。今やどのサイトもhttpsですね。
今回のSSL化に伴いWordPressが自動生成した『.htaccess』に追記する形でhttpへのアクセスをhttpsにリダイレクトさせるようにしました。
しかし、その過程で地味にハマったポイントがあります。
何故かトップページしかリダイレクトされなかったのです。
試行錯誤の結果、記述順序が影響していました。
ここでは、まずは取り急ぎ正しい対処法(『.htaccess』に書くべきコード全体)をご紹介した上で(読まなくても良いけど)解説も行います。
対処法
まずは取り急ぎ対処法です。
以下のコードの赤い部分をあなたの『.htaccess』の『# BEGIN WordPress』以前にコピペしてください。
(『# BEGIN WordPress』~『# END WordPress』の内容はWordPressによってサイトごとに自動生成されます。)
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</IfModule>
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
これでOKなはずです。TOPページだけでなく、ほかのページでもリダイレクトされるか見てみましょう。
気が向いたら続く解説も読んでみてください。
解説
では解説に入ります。
リダイレクトできればオッケー!っていう方は読まなくてOKです。
記述の順序が処理に大きな影響を与えています。
そもそも『# BEGIN WordPress』~『# END WordPress』に挟まれた領域に書いてはいけない
『# BEGIN WordPress』~『# END WordPress』に挟まれた領域はWordPressによって自動生成されます。
そして、自動で更新までされます。
つまり、なにかしらの設定をいじるとそれがトリガーとなって自動更新が行われ、あなたが書いたコードが無に帰します。
じゃあ『# END WordPress』の後に書けばいいのか!
実はこれにハマりました。
『# END WordPress』の後に書くと、現象としてはTOPページだけhttpsにリダイレクトされるという状態になります。
(正確にはこのサイトでいえば『http://tsuramin.com/』だけリダイレクトされます。『http://tsuramin.com/index.php』はされません。)
何故かというと、『# BEGIN WordPress』~『# END WordPress』内の処理に理由があります。
コードを日本語風に書くと
# WordPress の領域始まります
<実行条件 mod_rewrite.c っていうやつが使用可能なら実行してください>
RewriteEngine っていうやつを使用可能にします
書き換えるときのBaseは https://tsuramin.com/ にします
書き換えるぞ(対象:index.php, 処理:実はなんもしない(-), 処理後:ここから先は実行しない[L])
(↑逆に言えばindex.php以外が参照されるとこの先の処理に行きます。index.phpが参照されたら処理をやめて無限ループを防止します。)
もしも指定ファイルが存在しない(!-f)状態で
さらに指定ディレクトリが存在しない(!-d)ならば
書き換えるぞ(対象:すべて(.), 処理:(↑のBaseに続けて)index.php, 処理後:ここから先は実行しない[L])
</実行条件>
# WordPress の領域終わりです
となります。
これだけだと意味不明だと思うので、ここからは3通りのアドレスに対する挙動の違いを説明します。
ポイントは書き換え処理が発生すると実行終了するところにあります。
パターン①:『http://tsuramin.com/』はhttpsにリダイレクトされる
『http://tsuramin.com/』はこのサイトのルートディレクトリですので中身的にはindex.phpな感じがしますが、パスそのものはディレクトリを指しているのです。
index.phpではなくファイルでもないけど、ディレクトリが存在するので
さらに指定ディレクトリが存在しない(!-d)ならば
により直後の書き換え処理
書き換えるぞ(対象:すべて(.), 処理:(↑のBaseに続けて)index.php, 処理後:ここから先は実行しない[L])
を飛ばします。
書き換え処理の最後には実行終了が指定されていますが、処理が発生しないので終了せずに『# END WordPress』の後に行くことができます。
したがって、『# END WordPress』の後に書いてしまってもhttpsにリダイレクトされます。
パターン②:『http://tsuramin.com/index.php』はhttpsにリダイレクトされない
『http://tsuramin.com/index.php』はバッチリ
書き換えるぞ(対象:index.php, 処理:実はなんもしない(-), 処理後:ここから先は実行しない[L])
の処理対象です。
ここで実行終了してしまうので、その先に何を書いても無駄です。
したがって、httpsにはリダイレクトされません。
パターン③:『http://tsuramin.com/sashimi-hand』などもhttpsにはリダイレクトされない
『http://tsuramin.com/sashimi-hand』は今も存在するこのサイト上のコンテンツです。
一見すると、『sashimi-hand.html』か何かを参照しているように感じますが、実はそんなファイルは存在しません(詳細後述)。
なので
もしも指定ファイルが存在しない(!-f)状態で
に該当し、ディレクトリでもない(詳細後述)ので
さらに指定ディレクトリが存在しない(!-d)ならば
にも該当します。
以上により
書き換えるぞ(対象:すべて(.), 処理:(↑のBaseに続けて)index.php, 処理後:ここから先は実行しない[L])
の処理が行われ、httpのindex.phpにリダイレクトされて実行終了します。
したがって、httpsにはリダイレクトされません。
ところで、あなたは今、一体何を見ているのでしょう
ファイルでもない?ディレクトリでもない?
それは
『記事No.を渡されて、それをもとにコンテンツの内容をロードした状態のindex.php』です。
WordPressの仕組みとして
『http://tsuramin.com/(記事名とか記事N0.とか)』
というアドレスを打ち込むと
『(記事名とか記事N0.とか)』
の情報を保持したまま、パターン③のフローでindex.phpに案内されます。
案内先で、index.phpさんは情報を受け取り、ほかのphpの皆さんを叩き起こしながらコンテンツの内容をロードし、ページを生成します。
そうやって出来上がったのがあなたが今見ているものです。
なんだかややこしい話になってしまいましたが、普段何の気なしに使っているシステムってこんな感じだったんですね。
お役に立てば幸いです。