WordPress не обновляет одноразовый токен на сервере

У меня есть форма в моем плагине, похожая на эту:

<!-- Client form -->
<form>
<?php wp_nonce_field('my_form','_my_token'); ?>
<!-- Additional form fields -->
</form>

он генерирует эти два поля:

<input type="hidden" id="_my_token" name="_my_token" value="abcdefghij" />
<input type="hidden" name="_wp_http_referer" value="/wp-admin/tools.php?page=my-plugin%2Fplugin.php" />

Когда я отправляю эту форму, я проверяю ее следующим образом:

//Server's side check
if(!wp_verify_nonce($_POST['_my_token'],'my_form')){
echo 'Invalid token! Expected token: '. wp_create_nonce( 'my_form');
exit;
}

Проблема в том, что на сервере токен никогда не меняется, он всегда один и тот же, и проверка на этом этапе всегда заканчивается неудачей. Если я выйду из WordPress, а затем снова войду в систему, токен клиента изменился, но на сервере он изменился.

Я проверил это локально, и при повторном входе в систему он всегда меняет токен с обеих сторон, но в производственной среде он меняется только на стороне клиента.

Похоже, что он как-то кешируется, но не уверен, что именно может быть. Я использовал плагин WP Super Cache, но теперь он отключен, и эта проблема сохраняется. У меня включена многоузловая функция на моем производственном сайте, но я не думаю, что это связано с этим. Есть идеи?

4

Решение

В какие сроки вы ожидаете, что ваш nonce изменится?

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

Это по замыслу. Идемпотентное создание одноразовых номеров в течение короткого периода времени требуется для того, чтобы использовать их для проверки.

Еще раз, в принципе, если бы это не сработало, вы никогда не сможете проверить свой одноразовый номер. Когда вы его создали, значение было бы одной вещью, а когда вы пошли воссоздать его, чтобы проверить его, значение было бы другим. Проверка всегда будет неудачной.

wp_verify_nonce() может принять одноразовый номер (при прочих равных условиях) на срок до 24 часов (см. страница кодекса WP). Возможно, вам придется ждать дольше, чем это, чтобы получить другой одноразовый номер.

Другие системные события, которые могут произойти, могут привести к генерации нового одноразового номера. Мне никогда не нужно было делать это самому, но кажется, что вы можете использовать wp_nonce_tick() пробежать этот процесс.

Возможно, что один или оба wp_create_nonce() (используется непосредственно wp_nonce_field()) а также wp_verify_nonce() возможно, был переписан некоторым плагином, так как они оба определены в pluggable.php и предназначен быть доступным для переопределения. Хорошо написанный WPN-осведомленный CDN или другое решение для кэширования могут сделать именно это для сохранения сеансов. Я не знаю, делает ли Super Cache это или нет.

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

0

Другие решения

Других решений пока нет …