Что такое nonce и как использовать его с Ajax в WordPress?
Я пытаюсь изучить, как правильно использовать 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? Может кто-нибудь направить меня в правильном направлении?

Теперь я понял! WordPress просто потрясающий. Также спасибо knif3r, ваши советы очень помогли. Я попытаюсь объяснить это своими словами. Пожалуйста, поправьте меня, если я ошибаюсь.
Что такое nonce?
Nonce — это что-то вроде хеша безопасности для предотвращения атак и ошибок. Он создает уникальные идентификаторы для проверки, приходит ли ajax-запрос с веб-сайта или нет. Словами WordPress:
Nonce — это «число, используемое один раз», чтобы защитить URL-адреса и формы от определенных типов злоупотреблений, злонамеренных или иных. Nonce в WordPress — это не числа, а хеш, состоящий из чисел и букв. Они также не используются только один раз, а имеют ограниченный «срок жизни», после которого истекают.
Как его использовать?
Сначала нам нужно правильно добавить наш 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.
Теперь нам нужно использовать
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') )); }
Мы успешно зарегистрировали и локализовали наш скрипт.
Обязательно передайте данные 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 ) { // и т.д... } }, } );
Теперь мы хотим привязать нашу функцию к нашему скрипту. Для этого я использовал это:
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. Второй хук срабатывает, когда пользователь авторизован, а первый — когда нет.
Наша функция будет выглядеть так:
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, наша функция не будет отвечать им.
Извините за мой плохой английский и неидеальное объяснение. Просто пытаюсь помочь. Пожалуйста, дайте мне знать, если я что-то упустил или сделал что-то не так.

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

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

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

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

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