それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

HTTPSを強制する簡単な設定(htaccess)

httpでアクセスしてきたユーザーをHTTPSの暗号化に転送したい。

こういうこと

http://example.jp/index.php?a
             → https://example.jp/index.php?a #リダイレクト

.htaccess

RewriteEngine On
RewriteCond %{SERVER_PORT} !^443$
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R]

.htaccessmod_rewrite を組み合わせると簡単にできる。

色々やり方はあるんだけど。

virtualhost や Locationやらやり方はたくさんありますが(!%{HTTPS}とか。)。.htaccessなら置くだけで動くから楽ですね。

仕組みの解説

#mod_rewriteを有効にする
RewriteEngine On 
#書換条件: リクエストされたポートが443でない場合
RewriteCond %{SERVER_PORT} !^443$
# https付の同一サーバーの、同一パスに転送する
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R]

xreaとか共用SSLの場合は、%{SERVER_NAME}を任意のモノに書き換えておく。

備考


HTTPSを強制は、移行のためにやっています。

あるディレクトをHTTPSに変更しました。以前の通りHTTPのブックマークを使ったユーザーを、新しいHTTPSへ転送したかったのです。

HTTPSの強制や変更後は、HTTPアクセスに404を返すのがベターです。404でなく転送(301)をするのがセカンドベターです。


ポート80で待ち受けするのに、document root 全体を転送してる以下の例はどこか変なのです。ドキュメントルート全体にRewriteでHTTPSを強制するのはおかしいのです。

<VirtualHost *:80>
  # (省略)
  RewriteEngine On
  RewriteLog "logs/rewrite_log"
  RewriteLogLevel 0
  RewriteCond %{SERVER_PORT} !^443$
  RewriteRule ^/(.*)?$ https://%{HTTP_HOST}/$1 [L,R]
</VirtualHost>
http://app.assiona.to/archives/2009/12/192.html

こういう場合は、ErrorDocumentを使って転送するのがイイでしょう。たぶん上記のサイトの人は80番のドキュメントルートと443のドキュメントルート全体の区別がついていないと思います。

できるだけ、Rewriteせず、VirtualhostやDocumentRootの443ポート設定した方が良いです。

2016-04-24 追記

<VirtualHost *:80>
  # (省略)
  RewriteEngine On
#  RewriteLog "logs/rewrite_log"
#  RewriteLogLevel 0
  RewriteCond %{SERVER_PORT} !^443$
  RewriteRule ^/(.*)?$ https://%{HTTP_HOST}/$1 [L,R]
</VirtualHost>


RewriteLog と RewriteLogLevel は virtualHost のディレクティブで動かなかった。