はじめに
前回の記事のApacheの.htaccessで特定のディレクトリ/ファイルへのアクセスを禁止すると似ているが、今回は別のURLへリダイレクトするようにする。
※部分的に別のサーバに移行する場合を想定して作る。
環境
Windows 11 Professional
Docker Desktop 4.36.0 (175267)
Apache/2.4.62 (Debian)
準備
Apacheの.htaccessで特定のディレクトリ/ファイルへのアクセスを禁止する#準備と同様になる。
public/.htaccess
のみ異なるので記載する。
public/.htaccess
# mod_rewriteが有効である必要がある
## 特定のディレクトリへのアクセスをリダイレクトする
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^forbidden(/.*)?$ https://google.com [R=301,L]
</IfModule>
# 下記の場合、REQUEST_URI, QUERY_STRINGも引き継ぐ
#<IfModule mod_rewrite.c>
# RewriteEngine On
# RewriteRule ^forbidden(/.*)?$ https://google.com%{REQUEST_URI}?%{QUERY_STRING} [R=301,L]
#</IfModule>
リダイレクトについて
public以下のディレクトリ構造
├── public
├── access
│ ├── example.txt
│ ├── example2.txt
│ └── test.log
├── forbidden
│ ├── index.html
│ └── test
│ └── index.html
├── index.html
└── notaccess
└── index.html
リダイレクト表
パス | 結果 | 理由 |
---|---|---|
/index.html | リダイレクトなし | 設定に該当しないためリダイレクトされない |
/forbidden/index.html | https://google.com にリダイレクト | RewriteRule ^forbidden(/.*)?$ https://google.com [R=301,L] に一致 |
/forbidden/test/index.html | https://google.com にリダイレクト | /forbidden ディレクトリ配下であり、^forbidden(/.*)?$ に一致 |
/forbidden | https://google.com にリダイレクト | ディレクトリ自体のアクセスも ^forbidden(/.*)?$ に一致 |
/access/example.txt | リダイレクトなし | 設定に該当しないためリダイレクトされない |
/notaccess/index.html | リダイレクトなし | 設定に該当しないためリダイレクトされない |
/forbidden/test.log | https://google.com にリダイレクト | /forbidden 配下であり、RewriteRule に一致 |
/access/test.log | リダイレクトなし | 設定に該当しないためリダイレクトされない |
解説
リダイレクトされる条件:
RewriteRule ^forbidden(/.*)?$ https://google.com [R=301,L]
は、パスがforbidden
で始まるすべてのリクエスト(ディレクトリおよびその配下のファイル)にマッチする。リクエストが一致した場合、
https://google.com
にリダイレクトされる。
リダイレクトされない条件:
/forbidden
以外のディレクトリやファイルは、このRewriteRule
の条件に一致しないためリダイレクトされない。
REQUEST_URI, QUERY_STRINGを引き継ぐ際のリダイレクト表
コメントアウトしている下記を有効にした際のリダイレクト表
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^forbidden(/.*)?$ https://google.com%{REQUEST_URI}?%{QUERY_STRING} [R=301,L]
</IfModule>
この設定では、%{REQUEST_URI}
を使って元のリクエスト URI をリダイレクト先の URL に含める。
リクエストパス | リダイレクト先 | 理由 |
---|---|---|
/index.html | リダイレクトなし | 設定に該当しないためリダイレクトされない |
/forbidden/index.html | https://google.com/forbidden/index.html | RewriteRule ^forbidden(/.*)?$ に一致し、元の URI を引き継いでリダイレクトされる |
/forbidden/test/index.html | https://google.com/forbidden/test/index.html | /forbidden 配下であり、%{REQUEST_URI} に基づいてリダイレクトされる |
/forbidden/test.log | https://google.com/forbidden/test.log | 同上 |
/forbidden/ | https://google.com/forbidden/ | ディレクトリ自体のリクエストも引き継がれる |
/access/example.txt | リダイレクトなし | 設定に該当しないためリダイレクトされない |
/notaccess/index.html | リダイレクトなし | 設定に該当しないためリダイレクトされない |
解説
%{REQUEST_URI}
の役割:REQUEST_URI
変数は、元のリクエストされたパス(クエリ文字列を含む)を表す。これをリダイレクト先に含めることで、元のリクエストパスを新しい URL に引き継ぐ。
クエリ文字列の扱い:
?%{QUERY_STRING}
をリダイレクト先に追加することで、元のリクエストに含まれるクエリ文字列が引き継がれる。クエリ文字列がない場合は
?
は付加されない。
リダイレクトの動作:
/forbidden/
以下のパスとクエリ文字列が、https://google.com に含まれてリダイレクトされる。他のパスにはリダイレクトが適用されない。
テスト
.htaccess
のテストには以下のWebサイトを使うとよい。
- Test your htaccess rewrite rules
https://htaccess.madewithlove.com/
Fill in the url that you're applying the rules to.
に テストしたいURLを入れる。Paste your .htaccess rules into the form
に .htaccess
を入れる。
今回は、https://localhost/forbidden/?id=123 を入れた。
Output url
には、RewriteRule
で書き換えられたURLが出力される。
参考
Apache チュートリアル: .htaccess ファイル
https://httpd.apache.org/docs/2.4/ja/howto/htaccess.htmlApache Module mod_rewrite
https://httpd.apache.org/docs/2.4/ja/mod/mod_rewrite.html
おわりに
一部のディレクトリのみ別サーバに移動するということがあったため実践してみた。