2026年7月13日
2026年7月13日
WordPressでBasic認証と管理画面ログインを共存させる設定方法
WordPressの管理画面(wp-login.php と /wp-admin/)にBasic認証をかけると、WordPressのログインの手前にもう1枚の鍵が付き、総当たり攻撃の大半をPHPに届く前に止められます。ただし、何も考えずに /wp-admin/ 全体を保護すると、フロント側で使われる admin-ajax.php まで止まり、フォームや「いいね」ボタンなどが動かなくなります。この記事では、ApacheとNginxそれぞれで、サイトの機能を壊さずにBasic認証とWordPressのログインを二重にかける設定と、確認方法を説明します。
二重認証の仕組みと保護する範囲
Basic認証はWebサーバー(ApacheやNginx)が処理し、WordPressのログインはPHPが処理します。両者は独立しているため、Basic認証を通過した人だけがWordPressのログイン画面にたどり着ける、という順番になります。
保護すべき範囲と、除外すべき範囲は次のとおりです。
- 保護する:
wp-login.php、/wp-admin/配下 - 除外する:
/wp-admin/admin-ajax.php(フロント側のAjax処理に使われる)。プラグインによってはフロントのフォーム送信に/wp-admin/admin-post.phpを使うものもあるので、該当する場合は除外対象に加えます。 - 影響しない: トップページ、投稿、
/wp-json/(REST API)、wp-cron.php。ここは保護範囲に含めません。
サイト全体に鍵をかけるステージング環境の保護とは目的が異なります。この記事は「公開サイトの管理画面だけを守る」構成を扱います。
パスワードファイルを作る
Basic認証のユーザーとパスワードは .htpasswd ファイルに保存します。置き場所はドキュメントルートの外にします。公開ディレクトリに置くと、設定ミスでファイルがダウンロードされる危険があるためです。
# 初回のみ -c(ファイルを新規作成)。-B は bcrypt でハッシュ化
htpasswd -c -B /home/example/.htpasswd admin-gate
# 2人目以降は -c を付けない(付けると既存ファイルが上書きされる)
htpasswd -B /home/example/.htpasswd second-user
ユーザー名とパスワードは、WordPressのログイン情報とは別のものにします。同じにすると、片方が漏れたときに二重にした意味がなくなります。
レンタルサーバーでは、コントロールパネルにBasic認証(アクセス制限)の設定機能が用意されていることがあります。その場合はパネルから作る方が、サーバー側の推奨設定に沿うため安全です。ただし、パネルの機能はディレクトリ単位の保護が中心で、admin-ajax.php の除外まで面倒を見てくれるとは限りません。設定後に後述の確認を行ってください。
Apacheでの設定
Apache 2.4の書き方です。作業前に既存の .htaccess を保存しておきます。
wp-login.php を保護する
WordPressのルートにある .htaccess に追記します。WordPressが自動で書き換える # BEGIN WordPress から # END WordPress の間ではなく、その外側に書きます。
<Files wp-login.php>
AuthType Basic
AuthName "Admin Area"
AuthUserFile /home/example/.htpasswd
Require valid-user
</Files>
/wp-admin/ を保護し、admin-ajax.php を除外する
/wp-admin/ ディレクトリに新しく .htaccess を作ります。
AuthType Basic
AuthName "Admin Area"
AuthUserFile /home/example/.htpasswd
Require valid-user
<Files admin-ajax.php>
Require all granted
</Files>
Apache 2.4では、<Files> の中の Require が外側の Require valid-user を置き換えるため、admin-ajax.php だけが認証なしで通ります。
AuthName を wp-login.php 側と同じ文字列にしておくと、多くのブラウザでは一度入力した認証情報が使い回され、ログイン画面と管理画面で何度も入力を求められずに済みます。
固定IPからは認証を省く
事務所など固定のIPアドレスからだけ管理する場合は、そのIPを許可し、それ以外にはBasic認証を求める書き方もできます。
<RequireAny>
Require ip 203.0.113.10
Require valid-user
</RequireAny>
この場合、Require valid-user の1行をこのブロックに置き換えます。
Nginxでの設定
Nginxでは location の優先順位がつまずきどころです。location = /wp-login.php のような完全一致のブロックを作ると、PHPを処理する location ~ \.php$ が使われなくなるため、ブロックの中にPHPの処理を書き直す必要があります。
# wp-login.php に Basic 認証
location = /wp-login.php {
auth_basic "Admin Area";
auth_basic_user_file /etc/nginx/.htpasswd;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/php-fpm.sock;
}
# admin-ajax.php は認証なしで通す(完全一致が最優先される)
location = /wp-admin/admin-ajax.php {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/php-fpm.sock;
}
# /wp-admin/ 配下に Basic 認証
location ^~ /wp-admin/ {
auth_basic "Admin Area";
auth_basic_user_file /etc/nginx/.htpasswd;
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/php-fpm.sock;
}
}
fastcgi_pass のソケットパスや include するファイル名は環境によって違います。既存の location ~ \.php$ ブロックと同じ内容に合わせてください。変更後は nginx -t で構文を確認してから再読み込みします。構文エラーのまま再起動すると、サイト全体が止まります。
Nginxの場合 .htpasswd は /etc/nginx/ などWebの公開範囲外に置き、Nginxの実行ユーザーが読める権限にします。
設定後の確認
設定したら、ブラウザのプライベートウィンドウとcurlで次の点を確認します。
# 401 が返れば Basic 認証が効いている
curl -I https://example.com/wp-login.php
curl -I https://example.com/wp-admin/
# admin-ajax.php は 401 にならないこと(400 が返るのは正常)
curl -I https://example.com/wp-admin/admin-ajax.php
# 認証情報付きなら通ること
curl -I -u admin-gate https://example.com/wp-login.php
admin-ajax.php は action パラメーターなしで呼ぶとWordPressが400を返すため、ここでは「401ではないこと」を確認できれば十分です。
あわせて、フロント側でAjaxを使う機能(お問い合わせフォーム、絞り込み検索、カートなど)が動くか、管理画面の「ツール」→「サイトヘルス」で新しいエラーが出ていないかも確認します。サイトヘルスのループバックリクエストの確認は管理画面のURLへの内部アクセスを伴うため、Basic認証の影響で警告が出ることがあります。表示が出たら、サーバー自身のIPアドレスを Require ip で許可すると解消できる場合があります。
共存させるときの注意点
- HTTPSで使う: Basic認証のパスワードは暗号化されずに送られるため、HTTPのままでは盗聴されます。管理画面はHTTPSで運用してください。
- アプリケーションパスワードとの衝突: アプリケーションパスワードもBasic認証の形式で
Authorizationヘッダーを使います。REST APIの/wp-json/を保護範囲に含めると、外部連携が認証に失敗します。この記事の構成では/wp-json/を保護しないため影響しません。 - セキュリティプラグインのログイン URL 変更機能: ログインURLを変更する機能を併用すると、新しいURLは
wp-login.phpの<Files>指定から外れることがあります。どのURLが実際のログイン画面かを確認し、保護範囲を合わせます。 - 締め出しへの備え:
.htpasswdを紛失・破損すると管理画面に入れなくなります。FTPやSSHで.htaccessの該当部分を一時的に外せる手段を確保しておきます。
この記事の設定は、Apache 2.4系とNginxの一般的な構成を前提にしています(2026年10月現在)。レンタルサーバー独自の制限がある場合は、各社のマニュアルを優先してください。
まとめ
- Basic認証はWebサーバー、ログインはWordPressと処理する場所が別なので、二重の鍵として共存できます。
- 保護するのは
wp-login.phpと/wp-admin/、除外するのはadmin-ajax.php(必要に応じてadmin-post.php)です。 - Apacheでは
<Files>で除外し、Nginxでは完全一致のlocationで除外して、PHP処理の記述漏れに注意します。 - 設定後はcurlで401と非401を確認し、フロントのAjax機能とサイトヘルスも確認します。
.htpasswdは公開範囲外に置き、WordPressとは別の認証情報を使ってください。