質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
WordPress

WordPressは、PHPで開発されているオープンソースのブログソフトウェアです。データベース管理システムにはMySQLを用いています。フリーのブログソフトウェアの中では最も人気が高く、PHPとHTMLを使って簡単にテンプレートをカスタマイズすることができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

1回答

1554閲覧

wp_create_nonceを使い送信データの偽装を禁じ、通信を安全性を確保したいです

amegahutteruyo

総合スコア15

WordPress

WordPressは、PHPで開発されているオープンソースのブログソフトウェアです。データベース管理システムにはMySQLを用いています。フリーのブログソフトウェアの中では最も人気が高く、PHPとHTMLを使って簡単にテンプレートをカスタマイズすることができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2019/05/21 04:08

実現したいこと

wp_create_nonceを使い送信データの偽装を禁じ、通信を安全性を確保したいです

前提

前提として、このようなPHPで記事一覧とボタンが出力されます

▼single.php

<?php while ( $the_query->have_posts() ) :$the_query->the_post();?> <article> <h2><?php the_titiel();</h2> <button type="button" data-target_id="<?= $post->post_author; ?>">このユーザーを許可</button> </article> <?php endif; endwhile; wp_reset_postdata(); ?>

出力はこうなり、クリックするとdata-target_idupdate_user_metaを介して自分のDBに登録されます

▼HTML

<article> <h2>雨についての日記</h2> <button type="button" data-target_id="1">このユーザーを許可</button> </article> <article> <h2>雲についての日記</h2> <button type="button" data-target_id="2">このユーザーを許可</button> </article>

以上が前提です

ここで、DB登録についての安全性を考え、nonceを使いたいと思っています
そこで次のコードにたどり着きました

###該当のソースコード
▼functions.php

function my_enqueue_scripts_ajax() { $handle = 'my_script'; $jsFile = 'path/to/myscript.js'; wp_register_script($handle, $jsFile, ['jquery']); $action= 'my_ajax_action'; wp_localize_script($handle, 'MY_AJAX', [ 'api' => admin_url( 'admin-ajax.php' ), 'action' => $action, 'nonce' => wp_create_nonce( $action ), // ここをボタンの数だけ実行するのだと思いますが、それがわかりません ]); wp_enqueue_script($handle); } add_action( 'wp_enqueue_scripts', 'my_enqueue_scripts_ajax' );

しかし疑問があります

**『ボタンの数だけnonceを出力する方法』**です

おそらく**『'nonce' => wp_create_nonce( $action ),の部分を、ボタンの数だけ実行して、ボタンに見合ったnonceをs出力する』**のだと思いますが、その方法をご教授頂ければと思います

###行き詰っているところ
上のnonce出力コードはfunctions.phpに書いているので、single.phpのループでどんな記事が出力されるのかわからないはずです

そんな中で、どうやって**『'nonce' => wp_create_nonce( $action ),の部分を、ボタンの数だけ実行して、ボタンに見合ったnonceをs出力する』**ということが可能になるでしょうか?

###試したこと
それを可能にするために、single.phpのループの中にfunctions.phpのコードを置いてみました

▼single.php

<?php while ( $the_query->have_posts() ) :$the_query->the_post();?> <?php // ループの中でボタンの情報を取得します $target_id = get_theID(); // そしてここにfunctions.phpのコードを置いてみました function my_enqueue_scripts_ajax() { $handle = 'my_script'; $jsFile = 'path/to/myscript.js'; wp_register_script($handle, $jsFile, ['jquery']); $action= 'my_ajax_action'; wp_localize_script($handle, 'MY_AJAX', [ 'api' => admin_url( 'admin-ajax.php' ), 'action' => $action, ''.$name.'_nonce' => wp_create_nonce( 'my_ajax_'.$name.'_'.$target_id.'_allow' ), // ここでボタンに見合ったnonceが出力できるかと考えましたがだめでした ]); wp_enqueue_script($handle); } add_action( 'wp_enqueue_scripts', 'my_enqueue_scripts_ajax' ); ?> <article> <h2><?php the_titiel();</h2> <button type="button" data-target_id="<?= $post->post_author; ?>">このユーザーを許可</button> </article> <?php endif; endwhile; wp_reset_postdata(); ?>

エラーは出ませんでしたが、そもそもCDATAも出力されず、残念ながら実現したいことには至りませんでした

かなり調べてもこのようなケースが明確に記されたものは見当たらず、初心者の考えで申し訳なく思いつつも、質問サイトを利用させていただくことになりました

みなさまからご意見、ご回答をお待ちしております
どうぞ宜しくお願い致します

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

CHERRY

2019/05/21 04:34 編集

率直な疑問ですが、なぜ、ボタン毎に別々の nonce が必要と考えられているのでしょうか?
amegahutteruyo

2019/05/21 04:32

はい。CSRF対策としては1つのアクションに1つのnonceがあれば十分だという理解ですが、今回のように対象IDがあるときはその対象IDに応じたnonceが必要だという認識でございます nonceに対象IDが含まれていなければ、改ざんされたIDが送信されたときにその改ざんをはじけないのではないかという考えからの認識です もし間違った点がございましたらご指摘いただけましたら幸いです どうぞ引き続きのご指導を宜しくお願い致します
guest

回答1

0

wp_localize_script で設定する nonce は、Ajax リクエストのためのものですので、Ajax の action で1つです。

ボタン毎に nonce をつけると考えたことがないので、未確認ですが...

個々の button に nonce をつけたいのであれば、
wp_create_nonce を使って独自生成して、
wp_verify_nonce で検証することになるのではないかと思います。

感覚的には、ループの中で、

<button type="button" data-target_id="<?= $post->post_author; ?>" data-nonce="<?php echo wp_create_nonce( 'my-button-click' . $post->ID ); ?>">このユーザーを許可</button>

のように生成して、ボタンクリック時に nonce も一緒に送信するようなスクリプトにする。

検証する側でも、

wp_verify_nonce( $nonce, 'my-button-click' . $post_id );

のようなコードなると思うのですが、検証時にもアクションを指定する必要があるので何らかの方法で $post_id を得る必要があるのですが良い案が思いつきません。

投稿2019/05/21 07:05

CHERRY

総合スコア25171

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

CHERRY

2019/05/21 07:10

前提が、「ユーザー毎」ということであれば、 nonce のアクションに post ID ではなくて data-target_id に指定している $post->post_author を利用して、検証の際は、受け取った data-target_id を元にして nonce を検証するで対処できるのかなぁ...
amegahutteruyo

2019/05/21 07:38 編集

ご検討いただきまして誠にありがとうございます。 ボタンのデータ属性として nonce を出す案ですね。実は「ボタンに対応する nonce をそのままそのボタンに出すのは好ましくない」というような内容を(出典は失念してしまいましたが)拝読した記憶がございます。 そこに戸惑いがあるために、CDATAでグローバル変数として出力しておく方向を検討しておりました。 ところでもしその案でいくとすれば、検証は普通に ajax で ボタンの data-target_id を送信して、それを下記のように使う ▼single.php <button type="button" data-target_id="<?= $post->post_author; ?>" data-nonce="<?php echo wp_create_nonce( 'my-button-click' . $post->post_author . get_current_user_id() ); ?>">このユーザーを許可</button> ▼検証 wp_verify_nonce( $nonce, 'my-button-click' . esc_html( $_POST['data-target_id'] ) . get_current_user_id() ) ; という、コメント欄でCHERRY様が仰っている対処で良さそうに思いますが、何か思い当たる懸念がございますか? それにしても、送信される値の偽造を回避する(そのためにボタンごとにnonceを設定する)というのはよくありそうな処理かと思ったのですが、ネットにもなく、ユーザーランキング上位の方でも一考するものなのですね。意外でした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問