BLOG
WordPress REST APIをnonceで安全に使う方法【wp_create_nonce・permission_callback】
WordPressのREST APIをテーマ内から使うときは、単にエンドポイントを作るだけではなく、nonce と permission_callback をセットで考える必要があります。特に投稿保存、お気に入り登録、管理者向け操作など、ログインユーザーの権限に関係する処理では必須です。
この記事では、テーマ内JavaScriptから X-WP-Nonce を付けてPOSTし、REST API側で権限チェックする最小構成を作ります。
functions.php
<?php
add_action('wp_enqueue_scripts', function () {
wp_enqueue_script(
'theme-favorite',
get_template_directory_uri() . '/js/favorite.js',
[],
'1.0.0',
true
);
wp_localize_script('theme-favorite', 'themeFavorite', [
'root' => esc_url_raw(rest_url('theme/v1/favorite')),
'nonce' => wp_create_nonce('wp_rest'),
]);
});
add_action('rest_api_init', function () {
register_rest_route('theme/v1', '/favorite', [
'methods' => WP_REST_Server::CREATABLE,
'callback' => 'theme_save_favorite',
'permission_callback' => function () {
return current_user_can('edit_posts');
},
'args' => [
'post_id' => [
'required' => true,
'type' => 'integer',
'sanitize_callback' => 'absint',
],
],
]);
});
function theme_save_favorite(WP_REST_Request $request): WP_REST_Response
{
$post_id = (int) $request->get_param('post_id');
if ($post_id <= 0 || get_post_status($post_id) === false) {
return new WP_REST_Response([
'message' => '投稿が見つかりません。',
], 404);
}
update_user_meta(get_current_user_id(), 'theme_favorite_post', $post_id);
return new WP_REST_Response([
'post_id' => $post_id,
'saved' => true,
], 200);
}
JavaScript
const button = document.querySelector("[data-favorite-post]");
button?.addEventListener("click", async () => {
const postId = Number(button.dataset.favoritePost);
const response = await fetch(themeFavorite.root, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-WP-Nonce": themeFavorite.nonce,
},
credentials: "same-origin",
body: JSON.stringify({ post_id: postId }),
});
if (!response.ok) {
throw new Error("保存に失敗しました。");
}
const data = await response.json();
button.textContent = data.saved ? "保存しました" : "保存する";
});
nonceとpermission_callbackの役割
| 項目 | 役割 |
|---|---|
wp_create_nonce("wp_rest") | WordPress REST API用のnonceを発行する |
X-WP-Nonce | JavaScriptのfetchからnonceを送るためのヘッダー |
permission_callback | このエンドポイントを実行できるユーザーか判定する |
current_user_can() | WordPressの権限で操作可否を確認する |
よくある失敗
permission_callbackに__return_trueを入れたまま公開してしまう- ログインユーザー向けAPIなのに
credentials: "same-origin"を付け忘れる - nonceをURLに直書きしてキャッシュやログに残しやすくする
- REST API側で投稿IDや権限の再チェックをしない
あわせて読みたい
- REST APIを自作してWordPressからJSONを返す方法
- WordPressオリジナルテーマ開発で最初に作るべき便利関数10選
- WordPressで速報記事テンプレートを作る方法
- JavaScriptのfetchにタイムアウトを付ける方法【AbortSignal】