WordPress как на ладони
Наставник Трепачёв Д.П., phphtml.net wordpress jino

wp_verify_nonce() WP 2.0.4

Проверяет переданный проверочный код nonce.

Проверочный код создается одной из функций: wp_nonce_field(), wp_create_nonce(), wp_referer_field() или wp_nonce_url().

Про одноразовые числа читайте в отдельной статье.

Используется в: check_ajax_referer().
Хуки из функции:
Возвращает

false - если проверка не пройдена;
1 - если проверочный код был создан в последние 12 часов;
2 - если проверочный код был создан в промежуток между последними 12 и 24 часами.

Использование

if(  wp_verify_nonce( $nonce, $action ) ){}
$nonce(строка) (обязательный)
Код nonce, который нужно проверить. Обычно он передается в запросе: $_POST['_wpnonce'].
По умолчанию: нет
$action(строка)
Ключ, который был указан при создании nonce кода. Ключ по которому создавался код. Это необязательное значение, которое передается функции: wp_create_nonce('значение').
Если значение не было указано при создании ключа, то и тут его можно не указывать - проверка будет пройдена.
По умолчанию: -1

Примеры

#1. Пример проверки передаваемых данных по $_GET запросу:

<?php $nonce= wp_create_nonce('my-nonce'); ?>

<a href='myplugin.php?_wpnonce=<?php echo $nonce ?>&data=какие-то данные'> ...

<?php
// проверяем данные
if( wp_verify_nonce( $_GET['_wpnonce'], 'my-nonce') ){
	// обрабатываем данные формы
}
else
	die('Проверка не пройдена!'); 
?>

Код wp verify nonce: wp-includes/pluggable.php WP 4.8

<?php
function wp_verify_nonce( $nonce, $action = -1 ) {
	$nonce = (string) $nonce;
	$user = wp_get_current_user();
	$uid = (int) $user->ID;
	if ( ! $uid ) {
		/**
		 * Filters whether the user who generated the nonce is logged out.
		 *
		 * @since 3.5.0
		 *
		 * @param int    $uid    ID of the nonce-owning user.
		 * @param string $action The nonce action.
		 */
		$uid = apply_filters( 'nonce_user_logged_out', $uid, $action );
	}

	if ( empty( $nonce ) ) {
		return false;
	}

	$token = wp_get_session_token();
	$i = wp_nonce_tick();

	// Nonce generated 0-12 hours ago
	$expected = substr( wp_hash( $i . '|' . $action . '|' . $uid . '|' . $token, 'nonce'), -12, 10 );
	if ( hash_equals( $expected, $nonce ) ) {
		return 1;
	}

	// Nonce generated 12-24 hours ago
	$expected = substr( wp_hash( ( $i - 1 ) . '|' . $action . '|' . $uid . '|' . $token, 'nonce' ), -12, 10 );
	if ( hash_equals( $expected, $nonce ) ) {
		return 2;
	}

	/**
	 * Fires when nonce verification fails.
	 *
	 * @since 4.4.0
	 *
	 * @param string     $nonce  The invalid nonce.
	 * @param string|int $action The nonce action.
	 * @param WP_User    $user   The current user object.
	 * @param string     $token  The user's session token.
	 */
	do_action( 'wp_verify_nonce_failed', $nonce, $action, $user, $token );

	// Invalid nonce
	return false;
}

Cвязанные функции

Из метки: nonce (защита)

Еще из раздела: Защита

wp_verify_nonce 6 комментариев
  • campusboy1712 cайт: wp-plus.ru
    @

    Почему в примере используется?

    $nonce = $_REQUEST['_wpnonce']

    Обычно $_GET же. Есть какая-то принципиальная разница?

    Ответитьгод назад #
    • Kama4457

      Нет, в данном случае нет. Поправил код, спасибо!

      Ответитьгод назад #
      • campusboy1712 cайт: wp-plus.ru
        @

        Рад помочь! У меня появились вопросы по новой версии кода:

        if( wp_verify_nonce( @ $_GET['_wpnonce'], 'my-nonce') )

        Во-первых, разве $_GET может вызывать ошибку, которую надо подавить? Её может выдать wp_verify_nonce, если $_GET пустой будет, вот возле неё и нужно собачку ставить. Я верно рассуждаю?

        Во-вторых, большинство программистов утверждают, что использовать @ для подавления ошибок - плохой тон, лучше проверять входящие данные и, если они удовлетворяют нашим условиям, делать нужные действия. Так ли это?

        Ответитьгод назад #
        • Kama4457

          Если в get не указан параметр _wpnonce то появится notice - а тут это не к чему. Подавление ошибок плохой тон, да! Но это не правило...

          Плохой тон, потому что если говорить что это нормально, то начинающие прогеры, могут их подавлять там где в последствии может быть баг и появившейся notice на это укажет, у меня так бывало не раз, поэтому подавлять надо только тогда когда на 100% уверен так можно...

          В данном случае, как не крути бага тут не может быть, поэтому можно подавить... Не может быть, потому что допустим: мы подавили ошибку и вдруг при переделке кода, _wpnonce вообще не отправляется никогда - баг. Но в этом случае, проверка не будет пройдена и мы в любом случае выйдет на эту ошибку. К тому же конструкция с isset не покажет нам нотис если _wpnonce также не приходит...

          Хотя в противоречие своим словам, скажу что в WP подавление такого рода я не встречал. Почему? Можно разобраться, но я чет не хочу...

          Ну, я тоже скажу, для всех - это плохой тон smile Надо писать так:

          wp_verify_nonce( (isset($_GET['_wpnonce']) ? $_GET['_wpnonce'] : ''), 'my-nonce')

          К слову о таких вот подавлениях, в PHP 7 специально добавили оператор ??: подробнее тут

          Т.е. там можно писать без всяких подавлений:

          wp_verify_nonce( $_GET['_wpnonce']??'', 'my-nonce');

          Но до поддержки php 7 как до луны, а укорачивать хочется уже вчера... smile

          Если очень коротко, то можно сказать так, подавлять запрещено работы любых функций, хотя иногда и это необходимо, в частности в ядре WP можно встретить такие конструкции:

          @ opendir();
          @ chmod();
          @ unlink();
          1
          Ответитьгод назад #
          • campusboy1712 cайт: wp-plus.ru
            @

            Спасибо большое за пояснения, познавательно! Я просто стараюсь сразу писать "валидно", ибо потом плагин дебагинга для WP начинает светиться жёлтым (notice) или красным (error), что дико бесит и приходится делать, как надо. И это прекрасно на самом деле, со временем начинаешь машинально писать с проверками.

            PHP7, как ни странно, хостинги довольно быстро подхватили, мне тоже нравятся нововведения относительно сокращенных записей. Жаль, потом читать тяжело такой код, хотя ко всему ведь привыкаешь!

            Ответитьгод назад #
            • Kama4457

              Убрал из примера это подавление. Все таки так правильнее smile

              1
              Ответитьгод назад #

Здравствуйте, !

Ваш комментарий