
「このページだけ、この相手にだけ見せたい」——見積書や施工事例、公開前の校正用ページ、会員限定の資料。サイト全体を隠したいわけではなく、ページを1枚だけ、しかも渡す相手ごとに違う鍵で見せたい、ということがあります。
そうした「ページ単位の鍵」を実現する自作WordPressプラグイン「PageGuard」を紹介します。プラグインは無料でダウンロードできます。
目次
「このページだけ、この相手にだけ」が意外とできない
– サイト全体にBASIC認証をかける方法では、公開しているページまで見えなくなってしまう
– サーバーの `.htaccess` を編集する方法は、ディレクトリ単位が基本で、しかも書き間違えるとサイト全体が表示できなくなる
– WordPress標準の「パスワード保護」は手軽ですが、タイトルは一覧や検索結果に残ります
最後の点は見落とされがちです。中身は隠れていても、「〇〇株式会社様 御見積」というタイトルがトップページの新着一覧に並んでしまう、ということが起こります。
PageGuardは、保護したいページの編集画面でユーザー名とパスワードを入力するだけで、そのページにだけBASIC認証をかけ、同時にタイトルごとサイトから見えなくします。
WordPress標準の「パスワード保護」と何が違うのか
| WordPress標準の「パスワード保護」 | サイト全体のBASIC認証 | PageGuard | |
|---|---|---|---|
| 鍵の単位 | ページごと | サイト全体に1組 | ページごと |
| 資格情報 | パスワードのみ | ユーザー名+パスワード | ユーザー名+パスワード |
| パスワードの保存 | データベースに平文で保存 | 方式による | ハッシュ化して保存 |
| 一覧・検索結果 | タイトルは「保護中:」付きで出る | サイトごと見えない | 出ない |
| フィード(RSS) | タイトルが出る | サイトごと見えない | 出ない |
| サイトマップ | 掲載される | サイトごと見えない | 掲載されない |
| REST API | タイトル・URLは取得できる | サイトごと見えない | 404を返す |
| 総当たり対策 | なし | 方式による | あり(回数・時間を設定可) |
| キャッシュ対策 | なし | 方式による | キャッシュ禁止ヘッダーを付与 |
.htaccess の編集 | 不要 | 必要な場合が多い | 不要 |
要点は2つです。ユーザー名とパスワードの組を相手ごとに渡し分けられることと、保護したページがサイトのどこにも顔を出さなくなること。
なお「サイト全体のBASIC認証」は、公開前のサイトを丸ごと隠す用途では今も適切な方法です。PageGuardはそれを置き換えるものではなく、公開サイトの中に鍵のかかったページを混ぜるためのものです。
PageGuardについて
主な機能:
- 投稿・固定ページの編集画面で、そのページ専用のユーザー名/パスワードを設定
- 未認証のアクセスにはブラウザの認証ダイアログ(BASIC認証)を表示
- パスワードはハッシュ化して保存(平文では保存しません)
- 保護したページを、サイト内検索・アーカイブ一覧・フィード・サイトマップ・REST APIから除外
- 総当たり対策:認証の失敗が続いたアクセス元を一定時間ロック(既定は5回・900秒)
- そのページの編集権限を持つユーザーがログイン中の場合は、認証をスキップ
- 保護したページの応答にキャッシュ禁止ヘッダーを付与
- 設定画面で、対象の投稿タイプ・総当たり対策・ロック中のアクセス元・保護中のページ一覧を管理
対象にできる投稿タイプの既定は固定ページのみですが、設定画面から投稿やカスタム投稿タイプも追加できます。
インストール手順
- 記事末尾のリンクからzipファイルをダウンロードします。
- WordPress管理画面の「プラグイン > 新規プラグインを追加 > プラグインのアップロード」からzipをアップロードします。
- 「有効化」をクリックします。
外部ライブラリへの依存はありません。WordPress 6.7以上・PHP 7.4以上でご利用ください。
使い方
1. 保護したいページにIDとパスワードを設定する
保護したいページの編集画面を開くと、サイドバーに「PageGuard」の欄が表示されます。ユーザー名とパスワードを入力して更新するだけで、そのページに認証がかかります。

パスワードはハッシュ化して保存されるため、設定後に画面から読み出すことはできません。忘れた場合は新しいパスワードを設定し直してください(相手に伝えた控えは、別途手元に残しておいてください)。
2. 訪問者から見た動き
保護したページのURLにアクセスすると、ブラウザの認証ダイアログが表示されます。正しいユーザー名とパスワードを入力すると、ページが表示されます。

ダイアログを閉じた場合や、サーバーの構成によってダイアログが出なかった場合は、次の案内画面が表示されます。行き止まりにならないよう、入力をやり直すボタンを置いています。

誤りが規定回数続いたアクセス元は、一定時間ロックされます。ロック中は認証ダイアログではなく「しばらく待ってから再度お試しください」という応答を返します。
同時に、このページはサイト内検索の結果にも、カテゴリー一覧にも、RSSにも、サイトマップにも出てこなくなります。タイトルだけが残る、ということがありません。
3. 設定画面でできること
管理画面の 設定 > PageGuard を開くと、次の内容を確認・変更できます。

- 対象の投稿タイプ — 保護設定の欄をどの投稿タイプの編集画面に出すか(既定は固定ページのみ)
- 総当たり対策の調整 — 失敗を許す回数と、ロックする時間
- 受信診断 — お使いのサーバーで、ユーザー名/パスワードがPHPまで正しく届くかを判定します。届いていない場合は、解決の参考になる
.htaccessの記述例を表示します(自動での書き換えは行いません) - ロック中のアクセス元の確認・解除 — 総当たり対策でロック中のアクセス元を一覧表示し、個別に解除できます
- 保護中のページの一覧 — いま保護されているページを一覧できます
サイトがHTTPSで運用されていない場合は、設定画面の上部に警告を表示します。BASIC認証は毎回のリクエストでユーザー名とパスワードを送信するため、HTTPSでの運用を強く推奨します。
保護できる範囲と、できないこと
先に「できないこと」から書きます。ここを誤解したまま機密性の高い資料に使われるのが、いちばん困るためです。
- メディアファイルへの直リンクは保護できません。 画像やPDFのファイルURLは、WordPressを経由せずWebサーバーが直接返すため、URLを知っている人には見えてしまいます。これは今後のバージョンでも変わりません。機密性の高いファイルは、サーバー側の設定と併用してください。
- ナビゲーションメニューに登録したリンクは自動では消えません。 保護したページをメニューに載せている場合は、メニュー側からリンクを外してください。
- 検索プラグイン・SEOプラグインが独自に出力する検索結果やサイトマップには、タイトルが残ることがあります。それぞれの除外設定をご確認ください。
- すでに検索エンジンに登録された情報は対象外です。機密性の高い内容は、公開してから保護をかけるのではなく、公開前に保護を設定しておくことをおすすめします。
- 保護したページは、管理者がログイン中でもサイト表側の一覧には表示されません(理由は後述します)。管理画面の固定ページ一覧、または設定画面の「保護中のページ」から探してください。
保護されるのは、ページ本体の表示に加えて、サイト内検索・アーカイブ一覧・フィード・サイトマップ・REST API・前後の記事へのリンク・月別アーカイブ・そのページに付いたコメントです。WordPressの標準の仕組みを通って出力されるものは保護できる、と考えてください。
技術的な実装について
ページ本体だけを守っても意味がない
このプラグインで実装に一番手間がかかったのは、認証そのものではなく「本体以外の経路」を塞ぐ部分でした。
ページ本体に認証をかけても、RSSには本文が流れています。REST APIを叩けばJSONで中身が返ります。サイト内検索にはタイトルが出て、サイトマップにはURLが載っています。鍵をかけた玄関の横に、窓が5つ開いている状態です。
PageGuardは、REST API(単体取得は404、一覧・検索・oEmbedにも出さない)、フィード、サイト内検索とアーカイブ一覧、サイトマップ、前後の記事へのリンクと月別アーカイブ、コメント関連の出力を、それぞれ個別に除外しています。機能としては地味ですが、ここを省くと保護そのものが成立しません。
ログイン中の管理者にも、一覧には表示しない
保護したページは、管理者がログインしていてもサイト表側の一覧には出しません。「自分には見えたほうが便利では」と思われるかもしれませんが、これは意図的な設計です。
ログインの有無で出力内容を変えると、その出力がキャッシュに載ったときに、保護中のページの一覧が未ログインの訪問者へそのまま配られる恐れがあります。キャッシュプラグインやCDNを併用しているサイトでは、現実に起こりうる事故です。表示を出し分けないほうが、事故の起きようがありません。
同じ理由で、保護したページの応答にはキャッシュ禁止ヘッダーを付けています。認証を通した後の表示がキャッシュに載って、次の訪問者へ配られてしまっては元も子もないためです。
ロック中は「401」ではなく「429」を返す
総当たり対策でロックしている間、あえて認証ダイアログ(401)を返していません。429(Too Many Requests)と Retry-After ヘッダーを返しています。
401を返し続けると、ブラウザは認証ダイアログを出し続けます。閲覧者から見ると「正しいパスワードを入れているのに何度も聞かれる」という状態になり、何が起きているのか分かりません。429であれば「いま制限中で、いつ再開できるか」を画面で伝えられます。
締め出す相手は攻撃者ですが、実際にいちばん困るのは、パスワードを打ち間違えた正規の相手です。
動作要件
- WordPress – 6.7以上
- PHP – 7.4以上
- 外部ライブラリへの依存はありません。
ダウンロード
PageGuardを無料ダウンロードできます。
なお、このプラグインはAIエージェントに実装させる形で開発しました。1つのissueをどこまでの大きさで渡すと最後まで走りきるのか、レビュー役をどう設計したのか、といった実践記録は別記事にまとめています。
https://etbs.jp/blog/ai-agent/
有償サポートやカスタマイズをご希望の方は、弊社サポートページ からお問い合わせください。
自己紹介
インディーズでミュージシャンをやっていたのですがいつのまにか…
とある企業でショップのアルバイトスタッフから正社員、支店長を経てシステム部門に異動するという、開発担当としては変わった経緯を持っている方だと思います。
「Excel VBA」からスタートして、Yamaha RTX シリーズで VPN環境構築、Hyper-V環境構築、Windowsアプリ開発などを経験した後、「 WordPress 」に出会い、どっぷりハマっています。
現在勤めているETBS合同会社では、「 WordPress 」を活用したWEBサイト、業務用WEBアプリケーション開発を中心に、記事の執筆代行や掲載に必要な情報のリサーチ、映像のテロップ入れや切りはりなどの簡単な動画編集なども、まとめて行なっています。
宮崎県 都城市 出身。東京都 葛飾区 在住。現在、代表兼二児のパパ。子育てを通じて、こどもたちにもプログラミングの楽しさに触れてほしいと思うようになり、「 こどもICTかつしか教室 」を開講中。最近は童心に帰り、簡単なゲーム制作なんかも楽しんでいます(^_^)。







コメントを残す