wp_verify_nonce vs check_admin_referer - разница и когда использовать
В чем разница, какую из них следует использовать?
Я знаю, что wp_verify_nonce проверяет временное ограничение, а check_admin_referer, как я понимаю, вызывает wp_verify_nonce, а также проверяет наличие админского URL-сегмента, но я немного запутался, какую из них и когда следует использовать.
Спасибо за разъяснения.

Я думал, что функция check_admin_referer
проверяет nonce (она действительно вызывает wp_verify_nonce
), а также URL источника запроса. Однако, изучив исходный код ядра, я понял, что это не так. Подумав, что это баг, я сообщил об этом, и Райан Борен ответил следующее:
На самом деле, если nonce действителен, источник запроса не проверяется. Ненадёжность источников запросов — одна из причин, по которой используются nonce. Nonce полностью заменяют проверку источника запроса. Единственный случай, когда мы проверяем источник, — это обработка условия обратной совместимости -1. -1 означает, что кто-то не использует nonce, поэтому мы возвращаемся к проверке источника запроса. Такое использование сейчас встречается очень редко. Название функции
check_admin_referer()
сейчас неудачное, так как она почти никогда не проверяет источник запроса. Лучше было бы назвать её как-то вродеcheck_nonce()
, но мы оставляем её как есть для обратной совместимости и в память о старых временах.
Таким образом, фактически разницы нет.

На самом деле есть одно важное различие, влияющее на использование... check_admin_referer завершает весь скрипт с помощью die(), если nonce недействителен, тогда как wp_verify_nonce возвращает false. Поэтому если есть обычные ситуации, когда nonce может быть невалидным, используйте wp_verify_nonce, чтобы остальная часть скрипта продолжала выполняться.

НЕТ! БУДЬТЕ ВНИМАТЕЛЬНЫ!!!
Не полагайтесь на check_admin_referer()
без корректных параметров! Потому что в некоторых случаях она может не вызвать die()
(вопреки вашим ожиданиям), а просто вернуть ответ false
.
Посмотрите на логику поведения в исходном коде:
function check_admin_referer( $action = -1, $query_arg = '_wpnonce' ) {
$result = isset( $_REQUEST[ $query_arg ] ) ? wp_verify_nonce( $_REQUEST[ $query_arg ], $action ) : false;
//Теперь проверка на "die()"
if ( ! $result && ( -1 !== $action || strpos( wp_get_referer(), admin_url() ) !== 0 ) ) {
die();
}
return $result;
}
Итак, вам нужно понять, как работает эта логика. Вот разбор:
A) Если вы вызываете просто check_admin_referrer()
без параметров:
- ПОМНИТЕ, она будет использовать автоматически встроенное значение
_wpnonce
(это безопасно, но всё равно убедитесь, что это поле присутствует при отправке). - Поскольку вы вызвали её без параметров, она использует значение по умолчанию
-1
для действия, что приводит к пропуску проверкиdie()
, и функция не завершится сdie()
- Поэтому, при вызове без параметров всегда используйте:
if ( check_admin_referer() ) exit;
B) Если вы хотите, чтобы check_admin_referrer
завершалась автоматически, тогда всегда создавайте свои nonce и вызывайте её с параметрами:
check_admin_referrer($action_name, $name_field );
