この記事は最後に更新してから1年以上経過しています。

新「WordPress Events and News」ウィジェットが興味深い

説明

4.8のベータ版ですぐに新機能とわかるのが管理者ダッシュボードの新「WordPress Events and News」ウィジェット。ユーザーが指定した地域近隣で開催されるイベント情報を表示してくれるウィジェットで、この中のフォームがちょっと興味深かった。なおこの記事はWordPress 4.8 beta-2をもとにしており、以降のバージョンで変更される可能性があることをあらかじめ断っておく。

地域を指定するフォームにnonceがない

「WordPress Events and News」ウィジェット

「WordPress Events and News」ウィジェットの「地域登録フォーム」は通常は非表示になっており、「鉛筆」アイコンをクリックすることで表示と非表示を切り替えできる。この地域登録フォームのHTMLは次のようになっている(便宜上、空白文字を除外)。

<form class="community-events-form" aria-hidden="false" action="http://localhost/wp-admin/admin-ajax.php" method="post">
<label for="community-events-location">City:</label>
<input id="community-events-location" class="regular-text" type="text" name="community-events-location" placeholder="Cincinnati">
<input type="submit" name="community-events-submit" id="community-events-submit" class="button" value="送信">
<button class="community-events-cancel button-link" type="button" aria-expanded="true">キャンセル</button>
<span class="spinner"></span>
</form>

とてもシンプルな内容だが、「クイックドラフト」ウィジェットなどにある「クロスサイトリクエストフォージェリ(CSRF)」対策でおなじみの「nonce」設定が見当たらない。「nonce」設定をどこで行っているのか気になったので、リクエストの流れを追ってみた。

AJAXのリクエストハンドラを探す

4.8で追加されたAJAX関連を見ていくと、/wp-admin/includes/ajax-actions.phpにwp_ajax_get_community_events関数が追加されている。この関数の冒頭部分では次のように check_ajax_referer関数が呼び出されており、nonce値のチェックは行われていることがわかる。

check_ajax_referer( 'community_events' );

ここでチェックしているnonce値は動的に生成するものなので、「WordPress Events and News」ウィジェットのあるページに出力されていると予想して出力されたHTMLソースを見てみると、フッター部分のJavaScriptに次のような記述が見つかりました(そのままだと見難いので整形)。

var communityEventsData = {
	"nonce":"67f3177442",
	"cache":"",
	"l10n":{
		"enter_closest_city":"Enter your closest city to find nearby events.",
		"error_occurred_please_try_again":"An error occurred. Please try again.",
		"attend_event_near_generic":"Attend an upcoming event near you.",
		"could_not_locate_city":"We couldn’t locate %s. Please try another nearby city. For example: Kansas City; Springfield; Portland.",
		"city_updated":"City updated. Listing events near %s."
		}
	};

この変数の定義がどこで出力されているかというと、'admin_print_scripts-index.php'アクションとして実行されるwp_localize_community_events関数で wp_localize_script関数を使っていました。communityEventsData変数のconce値は、「地域登録フォーム」で「送信」ボタンが押された場合に動作する/wp-admin/js/dashboard.jsのgetEventsメソッドにおいてAJAXリクエスト時に使用されている。

requestParams          = requestParams || {};
requestParams._wpnonce = communityEventsData.nonce;
requestParams.timezone = window.Intl ? window.Intl.DateTimeFormat().resolvedOptions().timeZone : '';

initiatedBy = requestParams.location ? 'user' : 'app';

$spinner.addClass( 'is-active' );

wp.ajax.post( 'get-community-events', requestParams )

wp.ajax.postメソッドの第1パラメータで指定している'get-community-events'がWordPressのAJAXリクエストのactionパラメータ、第2パラメータが実際に送信されるパラメータ(この場合は$_POSTに格納される内容)のようだ。

これからのAJAXリクエストフォーム

JavaScriptのプログラム要素はファイルに記載し、リクエスト時の状況に応じて変動するデータをwp_localize_script関数で動的に出力するこの方法は個人的には好ましい。プラグイン開発においてフォームからAJAXリクエストする方法として参考にしたいと思う。


最終更新 : 2018年05月27日 10:43


お勧め

get_next_comments_link(2024年12月18日 更新)

string get_next_comments_link( [ string $label = '' [ , int $max_page = 0 [ , int $page = null ] ] ] )
次のコメントリンクを取得する。

add_dashboard_page(2022年6月27日 更新)

mixed add_dashboard_page( string $page_title, string $menu_title, mixed string $capability, string $menu_slug [ , mixed $function = '' ] )
ダッシュボードメニューにサブメニューを登録する。

use_block_editor_for_post(2023年4月24日 更新)

bool use_block_editor_for_post( int | WP_Post $post )
投稿がブロックエディターに対応しているか調べる。

wp_image_editor_supports(2012年12月20日 更新)

bool wp_image_editor_supports( [ mixed $args = array() ] )
イメージエディタがサポートしているか調べる。

wp_check_filetype_and_ext(2019年2月23日 更新)

array wp_check_filetype_and_ext( string $file, string $filename [ , array $mimes = null ] )
ファイルタイプと拡張子を調べる。