カスタマイズ

WordPress REST APIでヘッドレスCMSを実現する仕組みと標準エンドポイント

ヘッドレスCMS(表示部分を切り離し、コンテンツをAPI経由で配信する構成)は、WordPressなら追加インストールなしで始められる。管理画面で記事を書き、フロントのReactやNext.jsから/wp-json/wp/v2/postsを叩けばよい。この標準APIの構造さえ押さえれば、最短距離で組める。

具体的にどう便利なのかは、実際の配信シーンを思い浮かべると分かりやすい。たとえば、Next.jsで作った高速なコーポレートサイトと、同じ記事データを流用したスマホアプリの両方に、WordPress一つで配信できる。編集者はいつもの管理画面で更新するだけで、Webとアプリの両方に反映される。表示側をNext.jsやAstroに任せれば静的化やCDN配信でページ表示が速くなり、EC-CUBEやShopifyの店舗にブログ機能だけをAPIで差し込む、といった疎結合な構成も組める。「コンテンツ管理はWordPress、見た目は別技術」を無理なく両立できるのがヘッドレス化の実利だ。

ヘッドレスCMSの仕組みを表すイメージ

wp/v2が返すもの

コア標準の名前空間はwp/v2。投稿・ユーザー・タクソノミー用語をそれぞれWP_REST_Posts_ControllerWP_REST_Users_ControllerWP_REST_Terms_Controllerが担う。

コンストラクタではrest_baseが投稿タイプやタクソノミー側の設定を優先し、未設定ならnameにフォールバックする。カスタム投稿タイプの登録時にshow_in_restrest_baseを指定しておけば、独自エンドポイントが自動で生える。逆にこれを忘れるとフロントから一切見えず、原因の切り分けで時間を溶かすことになる。たとえば「products」というカスタム投稿タイプを作って商品情報をヘッドレス配信したい場合、show_in_resttrueにしておくだけで/wp-json/wp/v2/productsが使えるようになる。

register_rest_routeとpermission_callbackの役割

各コントローラーのregister_routes()は、WP_REST_Server::READABLE(GET)にget_itemsCREATABLE(POST)にcreate_itemを割り当てる。見落としがちなのが各ルートのpermission_callbackだ。アクセス可否を判定するこの関数こそが公開・非公開の境界であり、GETとPOSTで別々の判定関数が指定されている点に注意したい。

フロントからのリクエストが名前空間で振り分けられ、対応するコントローラーのget_itemscreate_itemに届き、permission_callbackで可否判定されるまでの流れ

図の要点は3つだ。 URLのwp/v2部分で名前空間が解決され、投稿・ユーザー・用語のどのコントローラーに渡すかが決まる。 HTTPメソッドでget_items(GET)とcreate_item(POST)が振り分けられる。 コールバック実行の直前に必ずpermission_callbackが走り、ここを通過して初めてデータが返る。トラブル時はこの3段階のどこで止まっているかを切り分ければ、原因に早くたどり着ける。

本番運用で詰まる認証・権限の落とし穴とApplication Passwordsによる解決

ヘッドレス構成で最も事故が起きるのは認証と権限まわりだ。「読めるはずのないデータが返る」「フロントから書き込めない」の大半は、permission_callbackの設計に起因する。

権限設定の穴

典型例は、独自エンドポイントのpermission_callback'__return_true'を置いたまま本番に出すパターンだ。常に許可を返すため、下書きや非公開投稿、ユーザーのメールアドレスまで無認証で漏れる。検証は単純で、ログアウト状態かシークレットウィンドウで対象URLを直接開き、非公開フィールドが含まれないかを目視する。あわせてcurlで認証ヘッダの有無を切り替えて叩き、レスポンスの差分を確認すれば確実だ。設定漏れは脆弱性対処の観点でも定期点検に含めたい。

Application Passwordsで組む認証

フロントからの書き込みには、WordPress 5.6以降の標準機能であるApplication Passwords(アプリ単位で発行するパスワード)が扱いやすい。エンドポイントはusers/<user_id>/application-passwordsで、user_idには数値のほか、自分自身を指すmeも使える。

公開GETのみのサイトなら認証は不要で、書き込みや非公開取得が絡むときにのみ導入すればよい。発行したパスワードはBasic認証としてサーバー間通信に載せるため、必ずHTTPS前提とし、フロントのブラウザ側JavaScriptには絶対に埋め込まないこと。漏えいすれば当該ユーザーの権限で操作されてしまう。API経由の投入経路を絞り込むほど、事故時の影響範囲も小さく保てる。たとえば、Next.jsのサーバーサイド(API RoutesやServer Actions)でのみパスワードを保持し、ブラウザには結果だけを返す構成にすれば、認証情報がクライアントに露出しない。

日本発!ECオープンプラットフォーム「EC-CUBE」 EC-CUBEゴールドパートナー EC-CUBEは株式会社イーシーキューブの商標です

カスタマイズに関するお問い合わせはこちら

    本記事のコード・挙動に関する記述は、WordPress 7.0.2 の実際のソースコードと照合して確認しています。