サポート » 使い方全般 » 「nonce」の使い方について

  • お世話になります。
    「nonce」の使い方について教えて頂けませんでしょうか。

    現在HTMLにこのようなボタンがあり、クリックするとuser metaの「’allow’」が更新されるPHPがあります。(JSは割愛)

    ▼HTML
    <button type="button" data-target_id="1">このIDを許可</button>

    ▼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' );	
    
    add_action( 'wp_ajax_my_ajax_action', 'my_ajax_event' );
    add_action( 'wp_ajax_nopriv_my_ajax_action', 'my_ajax_event' );
    function my_ajax_event() {
      $action = 'my_ajax_action';
      if( check_ajax_referer($action, 'nonce', false) ) {	
    		$u_id = get_current_user_id();
    		$target_id = esc_html( $_POST['target_id'] );
    		update_user_meta( $u_id, 'allow', $target_id );
    	}
      die();
    }

    で質問なのですが、ボタンが複数あったときは、どのようにしたらよろしいのでしょうか?

    つまりHTMLがこのようになっているときです。

    ▼HTML

    <button type="button" data-target_id="1">このIDを許可</button>
    <button type="button" data-target_id="2">このIDを許可</button>

    このようなときは、ボタン1つごとに別々のnonceを生成しなければならないのでしょうか?(もしそうであれば、それはどのように?)

    それとも「nonce」は上のPHPだけあれば、ボタンがいくつあっても適切なセキュリティで処理されるのでしょうか?

    「nonce」というのがよくわかっておらず以上のような疑問に至っておりますが、自力で解決できません。

    どなたかお助け頂けますと幸いでございます。
    宜しくお願い申し上げます。

10件の返信を表示中 - 31 - 40件目 (全40件中)
  • rararan998

    (@rararan998)

    @ishitakaさん

    最後に1点教えてくださいませ。

    「または」の方ではボタンごとのnonceを、ボタンと一緒に出力せずに、my_enqueue_scripts_ajax()を介してコメントアウトの形で次のように出力しているわけですよね。このように。

    'allow_nonce' => wp_create_nonce( 'my_ajax_action_1_allow' ),
    'add_nonce' => wp_create_nonce( 'my_ajax_action_1_add' ),

    しかしこの「1」は動的に変化します。上述したfunction echo_button( $target_id, $action_name ){}の、$target_idがそれです。(https://ja.wordpress.org/support/topic/%E3%80%8Cnonce%E3%80%8D%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6/page/2/#post-234997

    なのでやはり、ボタンごとのnonceを出力するには、ボタンと一緒に出力するしかないのではないでしょうか?
    my_enqueue_scripts_ajax()を介してコメントアウトの形で出力することはできないのではないでしょうか?

    それともここ(↓●)を動的に変化させる方法などありますでしょうか?

    'allow_nonce' => wp_create_nonce( 'my_ajax_action_●_allow' ),
    'add_nonce' => wp_create_nonce( 'my_ajax_action_●_add' ),

    この「動的なid」について、もしお時間ございましたら最後に教えて頂けますと幸いでございます。何卒…

    CG

    (@du-bist-der-lenz)

    変数をダブルクオーテーションで囲む場合には変数を{}で囲みます。囲まなくても問題無いことが多いですが、どこまでが変数名なのかを明示的に示すことで無用なエラーなどが起きませんので囲んでおきましょう。

    ishitaka

    (@ishitaka)

    $target_id が何か不明なため分かりませんが・・・

    function my_enqueue_scripts_ajax() {
    
    	(省略)
    
    	$target_id = ???
    
    	$action= 'my_ajax_action';
    	wp_localize_script( $handle, 'my_ajax', [
    		'api' => admin_url( 'admin-ajax.php' ),
    		'action' => $action,
    		'allow_nonce' => wp_create_nonce( "my_ajax_action_{$target_id}_allow" ),
    		'add_nonce' => wp_create_nonce( "my_ajax_action_{$target_id}_add" ),
    	]);
    	wp_enqueue_script( $handle );
    }
    rararan998

    (@rararan998)

    @du-bist-der-lenzさん

    こんばんは。どこまでが変数名なのかを明示的に示すとは、なるほどよく考えられてますね。ありがとうございます。

    rararan998

    (@rararan998)

    @ishitakaさん

    $target_id が何か不明

    失礼致しました。$target_idはユーザーのIDです。「このIDを許可」の、「どのIDか」を$target_idで指定します。

    そしてたしかに、my_enqueue_scripts_ajax()の中で$target_id = ???とすれば動的になるとは思うのですが、その$target_idは、my_enqueue_scripts_ajax()の中でしか使えませんよね。

    しかし$target_idは、前述のようにボタンを出力するときに「どのIDか」を示すためにも出力しておかなければなりません。

    つまり、「ボタンを出力するfunction echo_button( $target_id, $action_name ){}$target_id」と、「nonceを出力するwp_create_nonce( "my_ajax_action_{$target_id}_allow" )$target_id」を、同じにしなければならない。ということなんです。

    たとえば、ボタンを出力するときに次のようにします。
    これはpage.phpに書かれているものだとします。

    <?php $target_id = '1'; ?>
    <div class="user_actions">	
    	<?php echo_button( $target_id, 'allow' ); ?>
    </div>

    このボタンの$target_idを、nonceの$target_idと、同じにすることはできないのではないでしょうか?

    先ほどの「動的に」とは、このような「ボタンの$target_idと、nonceの$target_idを同じにする」という意味で申し上げたかったんです。

    わかりにくくて本当に申し訳ございません。

    ishitaka

    (@ishitaka)

    my_enqueue_scripts_ajax() の時点では $target_id が未定義なので出来ません。

    <?php $target_id = '1'; ?> を page.php の get_header() よりの前に配置できれば、

    function my_enqueue_scripts_ajax() {
    
    	(省略)
    
    	global $target_id;
    
    	$action= 'my_ajax_action';
    	wp_localize_script( $handle, 'my_ajax', [
    		'api' => admin_url( 'admin-ajax.php' ),
    		'action' => $action,
    		'allow_nonce' => wp_create_nonce( "my_ajax_action_{$target_id}_allow" ),
    		'add_nonce' => wp_create_nonce( "my_ajax_action_{$target_id}_add" ),
    	]);
    	wp_enqueue_script( $handle );
    }

    のように出来なくもないですが・・・スマートではないですね。

    • この返信は7 ヶ月前に  ishitaka さんが編集しました。
    rararan998

    (@rararan998)

    @ishitakaさん

    迅速なご返信に心より感謝申し上げます。
    なるほどグローバル変数にするんですね。
    (こちらはスマートさを判断できるレベルではないので気にしないでください。笑)

    ただ「このユーザーを許可」のボタンはユーザー一覧ページに出てくるボタンで、その$target_idget_header()より後の、ユーザーループ↓の中に書かざるをえなそうです。

    <?php
    // $author_id_arr はユーザーIDがたくさん入ってます
    if ( isset($author_id_arr) ) :
    ?>
    <ul class="users">	
    <?php foreach ( $author_id_arr as $author_id => $key ) : ?>
    	<li>
    		<div class="user_avatar">	
    			<?php echo_avatar( $author_id );?>					
    		</div>		
    		<?php $target_id = $author_id; ?>
    		<div class="user_actions">	
    			<?php echo_button( $target_id, 'allow' ); ?>
    		</div>					
    	</li>
    <?php endforeach; ?>
    </ul>

    でもこのようなケース(POSTされるユーザーIDを改ざんされないように、nonceにユーザーIDを含める)はよくありそうに思うのですが、どう解決してるんでしょうね。

    ishitaka

    (@ishitaka)

    同様の処理($target_id を取得する部分だけ)を my_enqueue_scripts_ajax() に書けばいいかと思います。

    rararan998

    (@rararan998)

    @ishitakaさん

    なー…る、ほど。上のユーザーループならばできそうな予感がします。

    my_enqueue_scripts_ajax()の中で、$author_id_arrを取得すればいいということです、よ…ね?

    ありがとうございます!

    あとは記事ループもありまして、ここでは執筆者としてユーザーIDが出力されています。

    こちらのユーザーIDは、

    ユーザーループのように「$author_id_arrから取得される」のではなく、

    「記事ループのWP_Queryから取得される」(記事ループの中でget_post_field( 'post_author', get_the_ID() );として取得される)ことになりますが、

    この場合ですといかがでしょうか。

    my_enqueue_scripts_ajax()の中で、記事ループ内のget_post_field( 'post_author', get_the_ID() );は、取得できますでしょうか?

    ishitaka

    (@ishitaka)

    同様に出来ると思いますが・・・。
    あとは、@rararan998 さんのコードをみた感じでは簡単に出来ると思います。頑張ってください。

    • この返信は7 ヶ月前に  ishitaka さんが編集しました。
10件の返信を表示中 - 31 - 40件目 (全40件中)
  • トピック「「nonce」の使い方について」には新たに返信することはできません。