[dot_recommends]
知らず知らずにやっている間違い。
以前はほとんどWordPressのプラグイン開発はしていなかったのですが、ここ1ヶ月ほどプラグイン開発していて、調べ物をしていてこちらのページを拝見しました。
そして、その先にリンクされているこちら(英語)。
いくつか思い当たることがあり、あわてて修正しました。
その中で特にこれはと思うものを2点の詳細を確認してみます。
1.(1.6.)カスタムな JavaScript や CSS をすべての管理者用ページに追加すること
さっくりと全ての管理画面にロードされるように作ってしまっていました。
大反省です。
不要な管理画面にまで、スクリプトやCSSがロードされるようにしてしまっていました。
具体的には
admin_enqueue_scripts
を使わずにadmin_print_scripts-(page_hook)
を使いましょう、ということです。
しかしこのアクションフック、実行タイミングによってうまくフックできません。
まだ(page_hook)が追加されていない状態で実行しようとすると、失敗します。
$hook = '';
/**
* Add menu
*/
function my_admin_menu() {
global $hook;
$hook = add_menu_page(
'プラグイン設定画面',
'設定画面',
BARB_AUTHORITY_,
'barb_settings',
'barb_disp_settings',
'dashicons-lock'
);
}
add_action('admin_menu', 'my_admin_menu');
/**
* Add admin style/javascript
*/
function my_admin_print_script_hook(){
wp_enqueue_style( 'barb_admin_style', plugins_url().'/barbpack/css/config.css' );
wp_enqueue_script( 'barb_admin_script', plugins_url().'/barbpack/js/config.js', array('jquery'));
}
add_action( "admin_print_scripts-$hook", 'my_admin_print_script_hook' );
フック名をアクションフックに渡すために、グローバル変数にしています。
しかし、これはうまく動作しません。
なぜなら、’admin_menu’のアクションフックより先にadd_action( “admin_print_scripts-$hook”, ‘my_admin_print_script_hook’ );が実行されて$hookには何も入っていないため、アクションフックの追加に失敗するのです。
これをちゃんと動作するようにするには、
/**
* Add menu
*/
function my_admin_menu() {
$hook = add_menu_page(
'プラグイン設定画面',
'設定画面',
BARB_AUTHORITY_,
'barb_settings',
'barb_disp_settings',
'dashicons-lock'
);
add_action( "admin_print_scripts-hook", 'my_admin_print_script_hook' );
}
add_action('admin_menu', 'my_admin_menu');
/**
* Add admin style/javascript
*/
function my_admin_print_script_hook(){
wp_enqueue_style( 'barb_admin_style', plugins_url().'/barbpack/css/config.css' );
wp_enqueue_script( 'barb_admin_script', plugins_url().'/barbpack/js/config.js', array('jquery'));
}
という風に、メニュー追加時にadmin_print_scripts-(page_hook)アクションフックを追加する必要があります。
2.(1.7.)セキュリティに配慮のないプラグインのフォーム、あるいは nonce の誤用
参考にさせていただいたサイトには、
「管理者ページからのリクエストかどうかは、wp_verify_nonce() ではなく、check_admin_referer() を用いるべし」とあります。
ちょっとあんまり深く考えずにwp_verify_nonce()を使っていました。
どうしてダメなんでしょうか。
codexにはwp_verify_nonce()について、他のコンテキストから渡されたnonceを確認となっており、特に管理画面から渡されたnonceかどうかはチェックしていません。
中途半端なCSRF(クロスサイトリクエストフォージェリ)脆弱性対策になってしまいます。
check_admin_referer()については管理画面から渡されたnonceを確認となっており、管理画面から送信されたデータかどうかを確認するためには、こちらを使う必要があるでしょう。
すでに経験豊富な方には当たり前のことかもしれませんが、他にも様々な気づきがありました。