تابع wp_verify_nonce در وردپرس
تابع wp_verify_nonce() یکی از ابزارهای مهم در وردپرس برای محافظت در برابر حملات CSRF (Cross-Site Request Forgery) است. در این مقاله بهصورت کامل عملکرد، کاربردها، مثالهای عملی و بهترین روشهای استفاده از این تابع را بررسی میکنیم تا بتوانید فرمها، درخواستهای AJAX و نقاط ورود سفارشی را امن کنید.
nonce در وردپرس چیست و چرا لازم است؟
واژه nonce مخفف “number used once” نیست دقیقاً در معنای سنتی، اما در وردپرس به یک توکن زمانیدار گفته میشود که برای اعتبارسنجی درخواستها استفاده میشود. nonceها از جعل درخواست میانسایتی جلوگیری میکنند و تضمین میکنند که عملیاتی که از طرف یک کاربر انجام میشود واقعاً توسط آن کاربر و در زمان معقولی صورت گرفته است.
چگونه nonce در وردپرس ساخته میشود؟
- wp_create_nonce( $action ) — تولید توکن متن ساده مبتنی بر اکشن.
- wp_nonce_field( $action, $name, $referer, $echo ) — اضافه کردن فیلد مخفی به فرمها.
- wp_nonce_url( $url, $action, $name ) — افزودن nonce به URLها.
تابع wp_verify_nonce() چیست؟
wp_verify_nonce( $nonce, $action ) مقدار nonce را بررسی میکند و بازگشتی از نوع عددی یا بولین دارد:
| نتیجه | توضیح |
|---|---|
| 1 | توکن معتبر و تولید شده در بازه زمانی فعلی (current tick) |
| 2 | توکن معتبر اما مربوط به بازه زمانی قبلی (previous tick) |
| false | توکن نامعتبر یا منقضی شده |
توجه: زمان عمر nonce پیشفرض در وردپرس با استفاده از فیلتر nonce_life قابل تغییر است. بهصورت پیشفرض وردپرس از دو “tick” 12 ساعته استفاده میکند، بنابراین nonce معمولاً تا 24 ساعت معتبر است.
مثال پایه: فرم با nonce و بررسی آن
<form method="post" action="admin-post.php">
<?php wp_nonce_field( 'my_plugin_action', 'my_plugin_nonce' ); ?>
<input type="hidden" name="action" value="my_plugin_save">
<input type="text" name="my_field" value="">
<input type="submit" value="ذخیره">
</form>در این مثال، فیلد مخفی nonce به فرم اضافه شده است. حال در تابع پردازش باید بررسی انجام شود:
function my_plugin_handle_post() {
if ( ! isset( $_POST['my_plugin_nonce'] ) ) {
wp_die( 'Nonce مشکل دارد.' );
}
$nonce = $_POST['my_plugin_nonce'];
if ( ! wp_verify_nonce( $nonce, 'my_plugin_action' ) ) {
wp_die( 'شرایط امنیتی رعایت نشده است.' );
}
// بررسی سطح دسترسی
if ( ! current_user_can( 'edit_posts' ) ) {
wp_die( 'اجازه دسترسی ندارید.' );
}
// ادامه پردازش و ذخیره دادهها
}
add_action( 'admin_post_my_plugin_save', 'my_plugin_handle_post' );توضیح: ابتدا بررسی میکنیم که مقدار nonce ارسال شده موجود است. سپس با wp_verify_nonce اعتبار آن را میسنجیم. در نهایت با current_user_can از دسترسی کاربر مطمئن میشویم. این سه گام پایهای برای امنیت فرمها هستند.
استفاده در AJAX
برای AJAX بهتر است از check_ajax_referer استفاده شود که هم nonce و هم referrer را میسنجد. اما میتوانید خودتان wp_verify_nonce را هم بهکار ببرید.
// در PHP (callback AJAX)
add_action( 'wp_ajax_my_action', 'my_ajax_handler' );
function my_ajax_handler() {
check_ajax_referer( 'my_ajax_action', 'security' ); // اگر نامش درست نباشد die میکند
// پردازش درخواست و ارسال پاسخ JSON
wp_send_json_success( array( 'message' => 'موفق' ) );
}توضیح: در سمت کلاینت، مقدار nonce را با wp_localize_script یا wp_create_nonce در جاوااسکریپت قرار دهید و آن را به همراه درخواست AJAX از طریق فیلد security ارسال کنید. check_ajax_referer بهصورت خودکار خطا را مدیریت میکند و امنتر از فرآیند دستی است.
نمونه جاوااسکریپت برای ارسال nonce
// PHP: enqueue script and localize nonce
wp_enqueue_script( 'my-script', plugin_dir_url(__FILE__).'my-script.js', array('jquery') );
wp_localize_script( 'my-script', 'MyPlugin', array(
'ajax_url' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( 'my_ajax_action' )
) );
// JS: ارسال درخواست AJAX
jQuery.post(MyPlugin.ajax_url, {
action: 'my_action',
security: MyPlugin.nonce,
data: { /* ... */ }
}, function(response) {
console.log(response);
});توضیح: در این الگو، wp_create_nonce در PHP مقدار nonce را میسازد و با wp_localize_script در دسترس JS قرار میگیرد. سپس در درخواست AJAX ارسال شده و در سمت سرور با check_ajax_referer بررسی میشود.
بهترین روشها و نکات امنیتی
- هرگز nonce را بهتنهایی بهعنوان مکانیزم احراز هویت استفاده نکنید؛ همیشه سطوح دسترسی (current_user_can) را بررسی کنید.
- برای هر عمل یک رشته action یکتا و معنادار انتخاب کنید (مثلاً ‘my_plugin_delete_item’).
- از توابع کمکی مثل check_admin_referer و check_ajax_referer استفاده کنید تا کار بررسی ساده و امن شود.
- اگر در REST API یا endpoint سفارشی هستید، از permission_callback در مسیرها استفاده کنید یا صریحاً wp_verify_nonce را به همراه بررسیهای دیگر بهکار ببرید.
- nonceها را ذخیره یا log نکنید؛ فقط تولید و بررسی کنید.
وقتی wp_verify_nonce نتیجهای غیرمنتظره دارد
اگر wp_verify_nonce همیشه false برمیگرداند:
- بررسی کنید که action یکسان باشد.
- مطمئن شوید nonce ارسال شده همان فیلدی است که در فرم تولید شده.
- احتمال وجود کش یا اختلاف زمانی (time drift) بین سرورها را در نظر بگیرید.
نمونه بهبود یافته: بررسی و پاسخ مناسب
if ( ! isset( $_POST['my_plugin_nonce'] ) || ! wp_verify_nonce( $_POST['my_plugin_nonce'], 'my_plugin_action' ) ) {
wp_send_json_error( array( 'code' => 'invalid_nonce', 'message' => 'خطای امنیتی.' ) );
}توضیح: بهجای wp_die در AJAX بهتر است از wp_send_json_error استفاده کنید تا پاسخ ساختاریافته JSON برگردانید و تجربه کاربری بهتری داشته باشید.
جمعبندی
wp_verify_nonce بخش مهمی از ابزارهای امنیتی وردپرس است که در کنار توابع تولید nonce و چکهای سطح دسترسی میتواند از بسیاری از حملات CSRF جلوگیری کند. به یاد داشته باشید که nonceها تنها بخشی از دفاع در عمق هستند و باید همواره با بررسی سطوح دسترسی، اعتبارسنجی دادهها و روشهای مناسب دیگر ترکیب شوند.
آیا این مطلب برای شما مفید بود ؟




