🐡

WordPress:すべては.htaccessでredirectされている

2024/01/09に公開

htaccess

phpのframeworkではよくある.htaccess
これで、配置されているディレクトリ以下は、rootディレクトリのindex.phpにアクセスして
frameworkで制御されるようになっている

実際のコード


# BEGIN WordPress
# "BEGIN WordPress" から "END WordPress" までのディレクティブ (行) は
# 動的に生成され、WordPress フィルターによってのみ修正が可能です。
# これらのマーカー間にあるディレクティブへのいかなる変更も上書きされてしまいます。
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress

最初のコメントから

# "BEGIN WordPress" から "END WordPress" までのディレクティブ (行) は
# 動的に生成され、WordPress フィルターによってのみ修正が可能です。
# これらのマーカー間にあるディレクティブへのいかなる変更も上書きされてしまいます。

いきなり、「直接いじるな」ということだと思っておいていいと思う

Apacheのmod_rewrite.cモージュルの確認

<IfModule mod_rewrite.c>

Ifがついているから、「もしあれば」みたいな感じというのがわかります

「mod_rewrite.c」ってなんだ?

mod_rewrite モジュールは、リダイレクトを制御できるモジュールですね
メンテナンスの時などに便利ですね

ここでは、あるかどうかの確認なので
あれば、</IfModule>までに記載しているコードを使用しますよ

さっそくリダイレクト機能をONにする

RewriteEngine On

説明もいらないくらいのコードですね
書き換えエンジンをONにする

条件なしのRewriteRule

RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

RewriteRule 正規表現パターン 置換URL [フラグ]
というルールで
RewriteRule .* -
「.*」 ← ワイルドカード 全アクセス
「-」 ← 何にも置き換えないでフラグだけ適用する

ということは、何も置き換えないけどすべてフラグだけ適用する

なので、次に
[E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
ついて考えてみる

[E=key:value]とすると環境変数keyに値valueを入れます。
ということは
HTTP_AUTHORIZATIONという変数名に
%{HTTP:Authorization}を設定する

%{HTTP:Authorization}って何?
BASIC認証情報など、HTTPの認証で利用された場合に情報が入る

サーバーによってはデフォルトでHTTP_AUTHORIZATIONが動作しない場合があるみたいで
設定するようにhtaccessに記載しているようだ

試しに下記コードでBASIC認証をすると
rootディレクトリのindex.phpに下記コード入力してみてなにか
ユーザー名とpasswordに入力してください

if (!isset($_SERVER['PHP_AUTH_USER'])) {
    header("WWW-Authenticate: Basic realm=\"My Realm\"");
    header("HTTP/1.0 401 Unauthorized");
    echo "キャンセルしました";
    exit;
} else {
    echo "<p>PHP_AUTH_USER {$_SERVER['PHP_AUTH_USER']} </p>";
    echo "<p>PHP_AUTH_PW {$_SERVER['PHP_AUTH_PW']} </p>";
}

echo $_SERVER['HTTP_AUTHORIZATION'];

ユーザー名:test
パスワード:test
と入力したら

$_SERVER['HTTP_AUTHORIZATION']には

Basic dGVzdDp0ZXN0

$_SERVER['PHP_AUTH_USER']は「test」
$_SERVER['PHP_AUTH_PW']は「test」
と表示されます

RewriteBase

RewriteBase /

RewriteBaseという名前の通り、リダイレクト時のベースを設定している
今回は
Rootディレクトリ直下のhtaccessに
/(ルートディレクトリ)を指定している
もし/newsディレクトリにwordpressを格納しているのであれば
/newsにしないといけない

RewriteRule

RewriteRule ^index\.php$ - [L]

書式は
RewriteRule 正規表現パターン 置換URL [フラグ]

index.php でまた「-」と置換せずフラグだけ設定する
[L]そこで終わりということ
次の行には、実行されずリダイレクトされる

RewriteCond

RewriteCond %{REQUEST_FILENAME} !-f

-f ファイルがある場合
の前に「!」がついているので否定
ということで今回は「ファイルがない場合」

RewriteCond %{REQUEST_FILENAME} !-d

-d ディレクトリがある場合
の前に「!」がついているので否定
ということで今回は「ディレクトリがない場合」

RewriteCondが2つ続けて記載されている場合
AND条件
「ファイルがない場合」AND「ディレクトリがない場合」に下記

続いて

RewriteRule . /index.php [L]

ドットはどんな条件でも適用するという条件
すべて/index.phpに置き換えられます

まとめ

  1. リダイレクト機能をONにして
  2. HTTP_AUTHORIZATIONがデフォルトで情報登録処理されないサーバー向けに処理
  3. 基準ディレクトリ指定して
  4. とりあえずどのディレクトリでも関係なしにindex.phpなら、そのまま表示して
  5. 「ファイルがない場合」AND「ディレクトリがない場合」にどんなアクセスでも基準ディレクトリ/index.phpにアクセス

気になったところ

4のindex.phpをつけてしまうと、とりあえずそこでリダイレクト処理が終わってしまうので、「/ないディレクトリ/index.php」だと、wordpressの処理に入らず、wordpressのPageNotFoundデザインにならない

5では、ディレクトリがある場合はアクセスできるので
「/wp-includes/」とか中身丸見え
「/wp-admin/」も管理画面アクセスできるのは、この仕組みなんだろう
この階層にも.htaccessでもいれてIP制限とかしといたほうが安全かも
できれば、wp-adminもフォルダ名を変えといた方がいいんじゃないかな

Discussion