Tetsujin’s blog

http://d.hatena.ne.jp/Tetsujin

mod_rewriteでリダイレクトあれこれ

ドメインの正規化

wwwあり・なしをどちらか片方に寄せたい場合。
今回はwww.example.comなど、example.com以外でアクセスされたらexample.comにリダイレクトする設定。

<VirtualHost *:80>
    # (1)
    ServerName  example.com
    ServerAlias www.example.com

    RewriteEngine On
    # (2)
    RewriteCond %{HTTP_HOST} !^example\.com
    # (3)
    RewriteRule .* http://example.com$0 [QSA,NE,R=301,L]
</VirtualHost>

(1)で、どちらのホスト名でもVirtualHostが動くようにする。

(2)は正規表現の末尾に$を付けないようにする。Hostリクエストヘッダは

Host = "Host" ":" host [ ":" port ] ; Section 3.2.2

http://www.studyinghttp.net/header#Host

と定義されているように、host名の後に「:ポート番号」が付与される形式がある。

例えば http://www.example.com:80/ にアクセスした場合に

Host: www.example.com:80

と送ってくるクライアントに対応できないので、前方一致で比較する。

(3)で

にアクセスした場合

にリダイレクトする。


リダイレクト時の各オプションは、

QSA

QueryString append。QSAを付与しないとQueryStringを上書いてします。詳しくは後述。

NE

No escape。URLエンコードを抑制する。NEを付与しないと、

にアクセスした場合に「%」が2重にエンコードされ

にリダイレクトされてしまう。

R=301

Moved Permanently

L

ここでルールの適用を終了する。


QSAはこの場合不要だけど、定義変更時に忘れがちなので付けておく。

HTTPSを強制

HTTPでアクセスされたらHTTPSにリダイレクトする。

RewriteEngine On
# (1)
RewriteCond %{HTTPS} !=on
RewriteRule .* https://example.com$0 [QSA,NE,R=301,L]

(1) SSL接続時にmod_ssl環境変数HTTPSにonをセットするのでそれで判断する。

DoCoMo機種の場合、強制的にguid=ONを付与

強制するのはどうなの?って感じですが。

RewriteEngine On
# (1)
RewriteCond %{HTTP_USER_AGENT} ^DoCoMo [NC]
# (2)
RewriteCond %{QUERY_STRING} !^(.*&)?guid=ON(&.*)?$ [NC]
# (3)
RewriteCond %{HTTPS} !=on
# (4)
RewriteRule .* http://example.com$0?guid=ON [QSA,NE,R=302,L]

(1) UserAgentがDoCoMoから始まるもの かつ
(2) QueryStringにguid=ONが含まれていない場合 かつ
(3) HTTPS接続で無い場合
(4) guid=ONを付与してリダイレクトする

ただし、アクセスする度にguid=ON付きURLにリダイレクトしたり、POSTのリクエストがリダイレクトされても困るので、
別途、アプリケーション側で内部リンクに自動的にguid=ONを付与するような仕組みを設けること。

(4)でR=302な理由は、DoCoMo端末のみのリダイレクト(!= Moved Permanently)であるのと、
301リダイレクトだと「サイトが移動しました(301)」のメッセージがでるので302を返すように。

(4)で「QSA」がついていないと、

にアクセスした場合に、Query Stringが書き換えられ

になってしまう。「QSA」が付与されていると

となる。

参考にさせていただいたリンク