序章
このチュートリアルでは、Apache2のmod_rewriteモジュールを使用してURL書き換えをアクティブ化し、管理する方法を学習します。 このツールを使用すると、URLをよりクリーンな方法で書き換えて、人間が読める形式のパスをコードに適したクエリ文字列に変換できます。
このガイドは2つに分かれています。1つ目はサンプルWebアプリケーションをセットアップし、2つ目は一般的に使用される書き換えルールについて説明しています。
前提条件
このチュートリアルに従うには、次のものが必要です。
- 1つの新しいUbuntu14.04ドロップレット
- このチュートリアルの手順2と3に従って設定できるsudo非rootユーザー
ステップ1—Apacheをインストールする
このステップでは、apt-getと呼ばれる組み込みのパッケージインストーラーを使用します。 管理が大幅に簡素化され、クリーンなインストールが容易になります。
まず、システムのパッケージインデックスを更新します。 これにより、古いパッケージや古いパッケージがインストールに干渉しないようになります。
sudo apt-get update
Apache2は前述のHTTPサーバーであり、世界で最も一般的に使用されています。 インストールするには、次のコマンドを実行します。
sudo apt-get install apache2
最も人気のある2つのオープンソースWebサーバーであるNginxとApache2の違いについては、この記事を参照してください。
ステップ2—mod_rewriteを有効にする
次に、mod_rewriteをアクティブ化する必要があります。
sudo a2enmod rewrite
これにより、モジュールがアクティブ化されるか、モジュールがすでに有効になっていることを警告します。 これらの変更を有効にするには、Apacheを再起動します。
sudo service apache2 restart
ステップ3—.htaccessを設定する
このセクションでは、書き換えルールの管理を簡単にするために、.htaccessファイルを設定します。
.htaccessファイルを使用すると、サーバー構成ファイルにアクセスせずに書き換えルールを変更できます。 このため、.htaccessはWebアプリケーションのセキュリティにとって重要です。 ファイル名の前のピリオドは、ファイルが非表示になるようにします。
開始する前に、さらにいくつかの設定をセットアップして保護する必要があります。
まず、.htaccessファイルの変更を許可します。 nanoまたはお好みのテキストエディタを使用して、デフォルトのApache設定ファイルを開きます。
sudo nano /etc/apache2/sites-enabled/000-default.conf
そのファイル内の1行目に<VirtualHost *:80>ブロックがあります。 そのブロック内に、次のブロックを追加します。
/etc/apache2/sites-available/default<Directory /var/www/html>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>
これで、ファイルは次のように一致するはずです。 すべてのブロックが適切にインデントされていることを確認してください。
/etc/apache2/sites-available/default<VirtualHost *:80>
<Directory /var/www/html>
. . .
</Directory>
. . .
</VirtualHost>
これらの変更を有効にするには、Apacheを再起動します。
sudo service apache2 restart
次に、.htaccessファイルを作成します。
sudo nano /var/www/html/.htaccess
新しいファイルの先頭にこの最初の行を追加して、RewriteEngineをアクティブにします。
/var/www/html/.htaccessRewriteEngine on
ファイルを保存して終了します。
他のユーザーが自分の.htaccessのみを読み取りできるようにするには、次のコマンドを実行して権限を更新します。
sudo chmod 644 /var/www/html/.htaccess
これで、Webアプリケーションのルーティングルールを管理するための操作可能な.htaccessファイルができました。
ステップ4—ファイルの設定
このセクションでは、基本的なURL書き換えを設定します。これにより、きれいなURLが実際のコードへのパスに変換されます。 具体的には、ユーザーがexample.com/aboutにアクセスできるようにします。
about.htmlという名前のファイルを作成することから始めます。
sudo nano /var/www/html/about.html
次のコードをHTMLページにコピーします。
/var/www/html/about.html<html>
<head>
<title>About Us</title>
</head>
<body>
<h1>About Us</h1>
</body>
</html>
your_server_ip/about.htmlまたはexample.com/about.htmlでWebアプリケーションにアクセスできます。 ここで、about.htmlのみにアクセスできることに注意してください。 your_server_ip/aboutにアクセスしようとすると、 NotFoundエラーが発生します。 代わりにaboutにアクセスしていただきたいと思います。 私たちの書き換えルールは、まさにこの機能を可能にします。
.htaccessファイルを開きます。
sudo nano /var/www/html/.htaccess
最初の行の後に、以下を追加します。
/var/www/html/.htaccessRewriteRule ^about$ about.html [NC]
これで、ファイルは次のようになります。
/var/www/html/.htaccessRewriteEngine on RewriteRule ^about$ about.html [NC]
おめでとう。 ブラウザでexample.com/aboutにアクセスできるようになりました。
これは、すべての書き換えルールが従う一般的な構文を示す簡単な例です。
^about$は、URLから照合される文字列です。 つまり、それは視聴者がブラウザに入力するものです。 この例では、いくつかのメタ文字を使用しています。
^は、example.com/が削除された後のURLの開始を示します。$はURLの終わりを示しますaboutは文字列「about」と一致します
about.htmlは、ユーザーがアクセスする実際のパスです。 つまり、Apacheは引き続きabout.htmlファイルを提供します。
[NC]は、URLの大文字と小文字を無視するフラグです。
上記のルールでは、次のURLはabout.htmlを指します。
example.com/aboutexample.com/Aboutexample.com/about.html
以下はしません:
example.com/about/example.com/contact
一般的なパターン
このセクションでは、一般的に使用されるディレクティブをいくつか示します。
これでWebアプリケーションが実行され、保護された.htaccessファイルによって管理されます。 最も単純な例は上に含まれています。 このセクションでは、さらに2つの例を検討します。
必要に応じて、結果パスにサンプルファイルを設定できますが、このチュートリアルにはHTMLファイルとPHPファイルの作成は含まれていません。 書き直しのルールだけです。
例1:RewriteRuleを使用したクエリ文字列の簡略化
すべてのRewriteRuleは、次の形式に従います。
RewriteRule pattern substitution [flags]
- RewriteRule :ディレクティブ
RewriteRuleを指定します - pattern :目的の文字列に一致する正規表現
- 置換:実際のURLへのパス
- flags :ルールを変更できるオプションのパラメーター
Webアプリケーションは、多くの場合、クエリ文字列を使用します。この文字列は、?疑問符を使用してURLに追加され、&アンパサンドを使用して区切られます。 書き換えルールを照合する場合、これらは無視されます。 ただし、ページ間でデータを渡すためにクエリ文字列が必要になる場合があります。 たとえば、PHPで記述された検索結果ページは、次のようなものを利用する場合があります。
http://example.com/results.php?item=shirt&season=summer
この例では、これを単純化して次のようにします。
http://example.com/shirt/summer
例1A:単純な交換
書き換えルールを使用すると、次のように使用できます。
/var/www/html/.htaccessRewriteRule ^shirt/summer$ results.php?item=shirt&season=summer
上記は、実際にはshirt/summerをresults.php?item=shirt&season=summerにマップするため、かなり自明です。 これにより、目的の効果が得られます。
例1B:マッチングオプション
ただし、これを一般化してすべての季節を含めたいと思います。 したがって、次のことを行います。
|ブール値(「OR」を意味する)を使用して一連のオプションを指定します()を使用して一致をグループ化し、次に$1を使用してグループを参照し、最初に一致したグループを1とします。
書き換えルールは次のようになります。
/var/www/html/.htaccessRewriteRule ^shirt/(summer|winter|fall|spring) results.php?item=shirt&season=$1
上記のルールは、shirt/の後に指定されたシーズンが続くURLに一致します。 そのシーズンは()を使用してグループ化され、後続のパスで$1を参照します。 これは、たとえば、次のことを意味します。
http://example.com/shirt/winter
になります:
http://example.com/results.php?item=shirt&season=winter
これにより、目的の効果も得られます。
例1C:文字セットのマッチング
ただし、/shirtのURLだけでなく、任意のタイプのアイテムも指定したいと思います。 したがって、次のことを行います。
- すべての英数字に一致する正規表現を記述します。 角かっこ式
[]はその中の任意の文字と一致し、+は角かっこで指定された任意の数の文字と一致します - 一致をグループ化し、ファイルの2番目の変数として
$2を使用して参照します
/var/www/html/.htaccessRewriteRule ^([A-Za-z0-9]+)/(summer|winter|fall|spring) results.php?item=$1&season=$2
上記は、たとえば次のように変換されます。
http://example.com/pants/summer
に:
http://example.com/results.php?item=pants&season=summer
例1D:クエリ文字列の受け渡し
このセクションでは、新しい概念を紹介しませんが、発生する可能性のある問題に対処します。 上記の例を使用して、http://example.com/pants/summerをリダイレクトしたいが、追加のクエリ文字列?page=2を渡すとします。 以下をお願いします。
http://example.com/pants/summer?page=2
マップする場所:
http://example.com/results.php?item=pants&season=summer&page=2
現在の設定で上記のURLにアクセスしようとすると、クエリ文字列page=2が失われていることがわかります。 これは、追加のQSAフラグを使用して簡単に修正できます。 以下に一致するように書き換えルールを変更すると、目的の動作が実現されます。
/var/www/html/.htaccessRewriteRule ^([A-Za-z0-9]+)/(summer|winter|fall|spring) results.php?item=$1&season=$2 [QSA]
例2:ロジックを使用した条件の追加
RewriteCondを使用すると、書き換えルールに条件を追加できます。 すべてのRewriteCondは、次の形式に従います。
RewriteCond TestString Condition [Flags]
- RewriteCond :
RewriteCondディレクティブを指定します - TestString :テストする文字列
- 条件:一致するパターン
- Flags :条件を変更する可能性のあるオプションのパラメーター
RewriteCondがtrueと評価された場合、直後のRewriteRuleが考慮されます。
例2A:デフォルトページ
架空の管理パネルでは、404でユーザーに挨拶するのではなく、すべての不正な形式のURLをホームページに戻すことができます。 条件を使用して、要求されたファイルが存在するかどうかを確認できます。
/var/www/html/.htaccessRewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^admin/(.*)$ /admin/home
これにより、/admin/blarghのようなものが/admin/homeにリダイレクトされます。
上記で:
%{REQUEST_FILENAME}はチェックする文字列です!-fはファイル名に!not演算子を使用しますRewriteRuleはすべてのリクエストを/admin/homeにリダイレクトします
より構文的および技術的に正しいアプローチは、404ErrorDocumentを定義することであることに注意してください。
/var/www/html/.htaccessErrorDocument 404 /error.html
例2B:IPアクセス制限
これは他の方法を使用して実現することもできますが、RewriteCondを使用して、1つのIPまたはIPアドレスのコレクションへのアクセスを制限できます。
この例では、を除くすべての場所からのトラフィックをブロックします12.34.56.789。
/var/www/html/.htaccessRewriteCond %{REMOTE_ADDR} !^(12\.34\.56\.789)$
RewriteRule (.*) - [F,L]
この例は、古いmod_rewrite記事からの例3の否定です。 ステートメント全体には、「アドレスが not 12.34.56.789の場合は、アクセスを許可しないでください」と記載されています。
要するに:
%{REMOTE_ADDR}はアドレス文字列です!^(12\.34\.56\.789)$は、すべての.ピリオドを\バックスラッシュでエスケープし、!を使用してIPアドレスを無効にします。Fフラグはアクセスを禁止し、Lフラグは、これが実行された場合に実行される最後のルールであることを示します
ブロック12.34.56.789が必要な場合は、代わりに次を使用してください。
/var/www/html/.htaccessRewriteCond %{REMOTE_ADDR} ^(12\.34\.56\.789)$
RewriteRule (.*) - [F,L]
元の記事のパート1とパート2で、より多くの書き換えルールとホットリンクを防ぐ方法を見つけることができます。
結論
mod_rewriteを効果的に使用して、人間が読めるURLを確保できます。 .htaccessファイル自体には、このモジュール以外にも多くの用途がありますが、その機能を拡張するために他の多くのApacheモジュールがインストールされている場合があることに注意してください。
mod_rewriteの機能を詳しく説明している他のリソースがあります。
mod_rewriteは、Webアプリケーションのセキュリティにとって重要なモジュールですが、リダイレクトループや、遍在するあいまいな500 forbiddenエラーが発生する場合があります。 .htaccessのデバッグに関するヒントについては、このStackOverflow投稿を参照してください。
書き換えルールは正規表現で記述されています。 エキスパートになるには、この正規表現に関するすべてのチュートリアルを参照してください。
正規表現パターンをすばやく分析するために、オンラインデバッガーを使用して、正規表現パターンの即時フィードバックとライブ解釈を提供できます。