mod_rewriteで、強制的にHTTPSからHTTPにする方法

HTTPとHTTPSで公開ディレクトリが同じ場合と、違う場合って存在しますよね。

公開ディレクトリが別だと、サイト共通の画像やJavaScript, CSSファイルまでコピーして配置しなければなりません。なんらかの手段で同期させればいいかもしれませんが、共用サーバーでは難しいのではないでしょうか(少なくとも私には良い案が思い浮かびません)

で、今回はHTTPとHTTPSで公開ディレクトリが同じ場合でのお話です。
URLをhttpsにするだけで、簡単にSSL通信ができて便利なのですが、検索エンジンから重複コンテンツとしてインデックスされてしまうとSEO的に好ましくなさそうですし、気分的にもいやです。
また、「このページはHTTPで、このページはHTTPSでアクセスさせたい!」ということが往々にしてあります。

今まではまあいいかとほったらかしていたのですが、今回仕事で必要が生じたため、このあたりを解決させてみました。

まず第一弾として、HTTPで強制的にアクセスさせる方法です。

HTTPでアクセスさせたい(SSLはダメ!)

そんな訳で真っ先に思いついたのがmod_rewriteでの実装です。
結論から言えば私の場合下記のようになったのですが、考えのステップを書いてみます。

完成型

RewriteEngine On
RewriteCond %{HTTP_HOST} !^(local.example.jp)(:80)? [NC]
RewriteCond %{SERVER_PORT} !^80$
RewriteCond %{REQUEST_FILENAME} (.htm|\/)$
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .* http://www.example.jp%{REQUEST_URI} [R=301,L]

mod_rewriteを有効に

これは説明がいりませんよね。mod_rewriteを有効にするおまじないです。

RewriteEngine On

テスト環境では適用しない

自分のローカルテスト環境ではlocal.example.jpとしてテストしているので、そこでもリダイレクトされると困ります。なのでテスト環境では適用しないようにします。

RewriteEngine On
RewriteCond %{HTTP_HOST} !^(local.example.jp)(:80)? [NC]

ポート80で無かったら

ポート80、つまりhttpの標準ポートで無かったら処理を行うようにします。

RewriteEngine On
RewriteCond %{HTTP_HOST} !^(local.example.jp)(:80)? [NC]
RewriteCond %{SERVER_PORT} !^80$

見方の違いなので、最後の行は下記でもいいでしょう(ポート443、つまりSSLだったら)。

RewriteCond %{SERVER_PORT} ^443$

HTMLファイルのみ

先ほどのままだと、画像ファイルやらなにやら全部HTTPになってしまいます。
最初これを記載せずにいて達成できたと思っていたのですが、SSLページ内で相対指定している画像がHTTPにされてしまい気がつきました。

下記によって、.htm拡張子およびディレクトリでのアクセスのみに限定して、HTTPにします。

RewriteEngine On
RewriteCond %{HTTP_HOST} !^(local.example.jp)(:80)? [NC]
RewriteCond %{SERVER_PORT} !^80$
RewriteCond %{REQUEST_FILENAME} (.htm|\/)$

(バックスラッシュは.htaccess内ではエスケープいらないのかもしれませんが一応。ちなみにエスケープ無しでも動きました)

ファイルORディレクトリが存在するときのみ、実行する

先ほどのままだと、https://www.example.jp/sonzaishinai_file.htm のような存在しないファイルまで、ご丁寧にhttpにリダイレクトしてしまいます。もちろんリダイレクト後にNot Foundになりますが、301リダイレクト(後述)しておいてNot Foundではなんだかよろしくなさそうです。

なので、ファイルORディレクトリが実際に存在するときのみ、実行するようにします。

RewriteEngine On
RewriteCond %{HTTP_HOST} !^(local.example.jp)(:80)? [NC]
RewriteCond %{SERVER_PORT} !^80$
RewriteCond %{REQUEST_FILENAME} (.htm|\/)$
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d

HTTPに301リダイレクトする

以上のコンディションが成立する際に、httpにリダイレクトします。
恒久的なリダイレクトを意味するR=301を指定します。

301を明示しないと302リダイレクトになってしまい、今回の目的においては検索エンジンに対してよろしくないからです。

RewriteEngine On
RewriteCond %{HTTP_HOST} !^(local.example.jp)(:80)? [NC]
RewriteCond %{SERVER_PORT} !^80$
RewriteCond %{REQUEST_FILENAME} (.htm|\/)$
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .* http://www.example.jp%{REQUEST_URI} [R=301,L]

完了!

てなわけで、HTTPSにアクセスされた際に、強制的にHTTPにする方法でした。
正しいかは分かりませんが、とりあえずこれで動いています。

普通のページはHTTPでアクセスするのが普通ですから、これを最上位ディレクトリにでも置いておけば、意図せずHTTPSでアクセスされてしまうことも無くなります。

後は、特定のディレクトリのみSSL対応にするよう設定すればいいだけです。
続きは次回に!

コメント

タイトルとURLをコピーしました