Что такое nonce и как использовать его с Ajax в WordPress?

8 июл. 2016 г., 18:42:19
Просмотры: 46.2K
Голосов: 9

Я пытаюсь изучить, как правильно использовать Ajax в WordPress. Вот что я узнал:

Шаг 1: Создать Ajax файл и зарегистрировать его с помощью wp_enqueue_script.

function wpdocs_theme_name_scripts() {
    wp_enqueue_script( 'script-name', get_stylesheet_directory_uri() . '/js/ajxfile.js', array(), '1.0.0', true );
}
add_action( 'wp_enqueue_scripts', 'wpdocs_theme_name_scripts' );

Шаг 2: Использовать ajax следующим образом в ajxfile.js:

$( document ).ready(function() {

$('#id').on('click',function (e){       
    alert("Это работает");
    var up = 1;
    var id = $( "#id" ).data( "user_id" );
    $.ajax({
            type: "POST",
                url: "runcode.php",
                data: {up:up, id:id},
                success:
                    function(result){
                alert("результат");
                        }
        });
});

});

ШАГ 3: добавление HTML на страницу:

<a href="#" id="id" data-user_id="<?php echo $user_id = get_current_user_id(); ?>" 
data-post_id="<?php echo $post_id = get_the_ID(); ?>">
       <i class="fa fa-thumbs-up" aria-hidden="true"></i>
</a>

Каждый раз, когда кто-то нажимает на ссылку, успешно срабатывает оповещение "Это работает". Теперь я хочу получить эти данные и добавить их в метаданные пользователя. Но это сбивает меня с толку. И что такое nonce? Может кто-нибудь направить меня в правильном направлении?

5
Комментарии

nonce — это уникальный идентификатор, который позже можно проверить с помощью PHP, чтобы убедиться, что это валидный и безопасный запрос. Он генерируется функцией wp_create_nonce() и проверяется либо с помощью wp_verify_nonce(), либо через параметр $_GET, или предпочтительным способом — filter_input(INPUT_GET, '$nonce');

knif3r knif3r
8 июл. 2016 г. 18:47:33

Но почему WordPress рекомендует его использовать? И как его правильно применять с AJAX?

Ramesh Pardhi Ramesh Pardhi
8 июл. 2016 г. 18:49:48

WordPress рекомендует его, потому что это хороший — нет, лучший способ проверить, что ваш запрос приходит оттуда, откуда вы ожидаете, и так, как вы ожидаете. Использование с AJAX — вы создаёте nonce в скрытом поле ввода, например, получаете его с помощью JavaScript, чтобы передать вместе с другими данными запроса, а затем в PHP используете параметр GET для его проверки.

knif3r knif3r
8 июл. 2016 г. 18:52:25

https://codex.wordpress.org/Function_Reference/check_ajax_referer Здесь вы можете найти хорошие примеры того, как и зачем использовать эту функцию. :)

knif3r knif3r
8 июл. 2016 г. 18:55:00

Ожидается, что вы проведёте исследование, хотя бы на нашем сайте, прежде чем задавать вопрос. Мы уже столько раз это обсуждали.

fuxia fuxia
8 июл. 2016 г. 20:47:49
Все ответы на вопрос 1
7
42

Теперь я понял! WordPress просто потрясающий. Также спасибо knif3r, ваши советы очень помогли. Я попытаюсь объяснить это своими словами. Пожалуйста, поправьте меня, если я ошибаюсь.

Что такое nonce?

Nonce — это что-то вроде хеша безопасности для предотвращения атак и ошибок. Он создает уникальные идентификаторы для проверки, приходит ли ajax-запрос с веб-сайта или нет. Словами WordPress:

Nonce — это «число, используемое один раз», чтобы защитить URL-адреса и формы от определенных типов злоупотреблений, злонамеренных или иных. Nonce в WordPress — это не числа, а хеш, состоящий из чисел и букв. Они также не используются только один раз, а имеют ограниченный «срок жизни», после которого истекают.

Как его использовать?

  1. Сначала нам нужно правильно добавить наш JS-файл с помощью wp_enqueue_script(). Например, так:

     function wpdocs_theme_name_scripts() {
         wp_enqueue_script( 'script-name', get_stylesheet_directory_uri().
             '/js/ajxfile.js', array(), '1.0.0', true );
     }
     add_action( 'wp_enqueue_scripts', 'wpdocs_theme_name_scripts' );
    

Мы регистрируем наш файл ajxfile.js с именем script-name. Теперь он загружается на всех страницах нашего WordPress.

  1. Теперь нам нужно использовать wp_localize_script(), чтобы объявить наши переменные, и здесь мы добавляем наш nonce для использования в функциях.

     function wpdocs_theme_name_scripts() {
         wp_enqueue_script( 'script-name', get_stylesheet_directory_uri() . 
             '/js/ajxfile.js', array(), '1.0.0', true );
         wp_localize_script('script-name', 'ajax_var', array(
             'url' => admin_url('admin-ajax.php'),
             'nonce' => wp_create_nonce('ajax-nonce')
         ));
     }
    

Мы успешно зарегистрировали и локализовали наш скрипт.

  1. Обязательно передайте данные nonce в вашем ajax-запросе в ajxfile.js:

     /* global ajax_var */
     $.ajax( {
         url: ajax_var.url,
         type: 'post',
         data: {
             action: 'custom_script_name',
             nonce: ajax_var.nonce,   // передаем nonce здесь
             moredata: 'whatever',
         },
         success( data ) {
             if ( data ) {
                 // и т.д...
             }
         },
     } );
    
  2. Теперь мы хотим привязать нашу функцию к нашему скрипту. Для этого я использовал это:

     add_action('wp_ajax_nopriv_custom_script_name', 'custom_php_ajax_function');    
     add_action('wp_ajax_custom_script_name', 'custom_php_ajax_function');
    

Мы используем wp_ajax_nopriv_ и wp_ajax_, чтобы привязать наши функции к хукам WordPress. Второй хук срабатывает, когда пользователь авторизован, а первый — когда нет.

  1. Наша функция будет выглядеть так:

     function custom_php_ajax_function() {
         // Проверяем nonce для безопасности      
         if ( ! wp_verify_nonce( $_POST['nonce'], 'ajax-nonce' ) ) {
             die ( 'Busted!');
         }
     }
    

Наша функция проверит, отправляет ли ajax данные скрытое значение nonce вместе с другими параметрами. Если нет, то вызовется ошибка. Это действительно может помочь предотвратить ajax-атаки. Данные nonce — это скрытое значение, которое обязательно должно отправляться с другими параметрами.

Как проверить, работает ли это?

  • Удалите 'nonce' => wp_create_nonce('ajax-nonce') из wpdocs_theme_name_scripts() и нажмите на ссылку. Это вызовет ошибку.
  • Теперь удалите проверку безопасности из нашей функции и нажмите на ссылку. Она сработает.

Это показывает, что наша функция с проверкой nonce никогда не сработает, если нет данных nonce. Они скрыты, поэтому никто другой не может их использовать. И если никто не знает их, то сколько бы раз они ни запускали этот ajax, наша функция не будет отвечать им.

Извините за мой плохой английский и неидеальное объяснение. Просто пытаюсь помочь. Пожалуйста, дайте мне знать, если я что-то упустил или сделал что-то не так.

8 июл. 2016 г. 20:06:50
Комментарии

Небольшое уточнение: wp_ajax_nopriv_ предназначен для пользователей, которые НЕ вошли в систему (у них "нет привилегий"), а wp_ajax_ — для пользователей, которые вошли в систему. Вы указали наоборот.

scott scott
8 июл. 2016 г. 21:02:02

Кажется, вы всё правильно поняли :) Просто не забывайте использовать функции фильтрации при работе с POST/GET/REQUEST запросами, например filter_input(INPUT_POST 'datasource'); или другие PHP-функции типа htmlspecialchars(), esc_attr() или esc_html, когда используете скрытые поля для передачи данных в JS, и тогда всё будет в порядке.

knif3r knif3r
8 июл. 2016 г. 21:29:01

Спасибо, Скотт, я обновил ответ. Да, knif3r, спасибо за совет. Я буду помнить об этом.

Ramesh Pardhi Ramesh Pardhi
9 июл. 2016 г. 10:36:15

хороший ответ. Я просто добавил шаг, где nonce данные должны быть переданы в вызов $.ajax

squarecandy squarecandy
28 янв. 2021 г. 01:48:45

Очень хорошо объяснено - спасибо

Clinton Clinton
15 мар. 2021 г. 17:06:12

Это очень помогает, но я не понимаю, почему в теле ответа я всегда получаю 0.

noob noob
1 нояб. 2022 г. 12:55:43

Хорошо объяснено, @RameshPardhi

Krupal Panchal Krupal Panchal
1 дек. 2022 г. 11:37:50
Показать остальные 2 комментариев