Nonce是number used once的縮寫,Wordpress的nonce不是數(shù)字,而一是字串由數(shù)字和字元組成的Hash值,不僅只能使用一次,還同時具有生命週期(lifetime),在生命週期內(nèi),針對每個用戶,同樣的參數(shù)會產(chǎn)生相同的nonce值,直到生命週期結(jié)束。這篇文章我們就來介紹如何用Nonce來防止CSRF攻擊。
建立一個Nonce
Nonce可以放在Url請求中,也可以放在一個Form的Hidden元素中,然後當(dāng)Ajax請求時,透過Javascript來獲取他它。一個Nonce生命週期只在目前Session中,如果你登出登入後再登入,之前的nonce也會失效。
在URL中加入nonce
你可以透過wp_nonce_url()方法來為Url新增一個Nonce:
wp_nonce_url(?$actionurl,?$action,?$name?); //?例如: $complete_url?=?wp_nonce_url(?$bare_url,?'trash-post_'.$post->ID?);
其中$bare_url(必選)為要加入nonce的url,而$action為nonce定義的動作名字,可選,預(yù)設(shè)為-1。
預(yù)設(shè)情況下,產(chǎn)生的nonce在連結(jié)中的名字為_wpnonce,為了避免可能的衝突,在Wordpress3.6版本後,wp_nonce_url增加了可選的$name參數(shù),可以讓使用者自己指定nonce在連結(jié)中的名字。如:
$complete_url?=?wp_nonce_url(?$bare_url,?'trash-post_'.$post->ID,?'my_nonce'?);
向Form新增nonce
你可以能過wp_nonce_field()方法新增一個hidden元素在表單中:
PHP wp_nonce_field(?$action,?$name,?$referer,?$echo?) //例如?: wp_nonce_field(?'delete-comment_'.$comment_id?); wp_nonce_field(?$action,?$name,?$referer,?$echo?) //例如?: wp_nonce_field(?'delete-comment_'.$comment_id?);
調(diào)用上面的方法,會產(chǎn)生類似下面的程式碼:
<input type="hidden" id="_wpnonce" name="_wpnonce" value="796c7766b1" /> <input type="hidden" name="_wp_http_referer" value="/wp-admin/edit-comments.php" />
單獨(dú)產(chǎn)生一個nonce
如果你只是想要產(chǎn)生一個獨(dú)立的nonce,可以過wp_create_nonce()方法:
wp_create_nonce(?$action?); //?例如: $nonce?=?wp_create_nonce(?'my-action_'.$post->ID?);
同樣的,$action為可選參數(shù),預(yù)設(shè)為-1。上面的方法會回傳類似「295a686963」的結(jié)果。
驗(yàn)證nonce有效性
驗(yàn)證表單中的nonce
在Admin管理介面,你可以透過check_admin_referer方法來驗(yàn)證Url中Nonce的有效性:
check_admin_referer(?$action,?$query_arg?);
下面是一個範(fàn)例示範(fàn)如何在外掛程式中使用check_admin_referer驗(yàn)證nonce:
<form method="post"> ???<!-- some inputs here --> ???<?php wp_nonce_field( 'name_of_my_action', 'name_of_nonce_field' ); ?> </form>
驗(yàn)證方法:
check_admin_referer(?'name_of_my_action',?'name_of_nonce_field'?);
#驗(yàn)證Ajax中的nonce
如果要檢查Ajax請求中的nonce有效性,可以使用check_ajax_referer()方法:
check_ajax_referer(?$action,?$query_arg,?$die?)
$die指定如果$nonce無效,是否結(jié)束腳本執(zhí)行。 (預(yù)設(shè)為True)
一個簡單使用check_ajax_referer的範(fàn)例:
<?php //Set Your Nonce $ajax_nonce = wp_create_nonce( "my-special-string" ); ?> ? <script type="text/javascript"> jQuery(document).ready(function($){ ????var?data?=?{ ????????action:?'my_action', ????????security:?'<?php echo $ajax_nonce; ?>', ????????my_string:?'Hello?World!' ????}; ????$.post(ajaxurl,?data,?function(response)?{ ????????alert("Response:?"?+?response); ????}); }); </script>
在向後透過下面的程式碼進(jìn)行驗(yàn)證:
add_action(?'wp_ajax_my_action',?'my_action_function'?); function?my_action_function()?{ ????check_ajax_referer(?'my-special-string',?'security'?); ????echo?sanitize_text_field(?$_POST['my_string']?); ????wp_die(); }
#驗(yàn)證獨(dú)立產(chǎn)生的nonce
1 wp_verify_nonce(?$nonce,?$action?);