Nonce是number used once的缩写,Wordpress的nonce不是数字,而一是串由数字和字符组成的Hash值,不仅只能使用一次,还同时具有生命周期(lifetime),在生命周期内,针对每个用户,同样的参数会生成同样的nonce值,直到生命周期结束。这篇文章我们就来介绍一下如何用Nonce来防止CSRF攻击。
创建一个Nonce
Nonce可以被放在Url请求中,也可以放在一个Form的Hidden元素中,然后在Ajax请求时,通过Javascript来获取他它。一个Nonce生命周期只在当前Session中,如果你退出登录后再次登录,之前的nonce也都会失效。
向URL中添加nonce
你可以通过wp_nonce_url()方法来向Url中添加一个Nonce:
1 2 3 | wp_nonce_url( $actionurl , $action , $name );
$complete_url = wp_nonce_url( $bare_url , 'trash-post_' . $post ->ID );
|
Salin selepas log masuk
其中$bare_url(必选)为要添加nonce的url,而$action为为nonce定义的动作名字,可选,默认为-1。
默认情况下,生成的nonce在链接中的名字为_wpnonce,为了避免可能的冲突,在Wordpress3.6版本后,wp_nonce_url增加了可选的$name参数,可以让用户自己指定nonce在链接中的名字。如:
1 | $complete_url = wp_nonce_url( $bare_url , 'trash-post_' . $post ->ID, 'my_nonce' );
|
Salin selepas log masuk
向Form中添加nonce
你可以能过wp_nonce_field()方法向表单中添加一个hidden元素:
1 2 3 4 5 6 7 8 | 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 );
|
Salin selepas log masuk
调用上面的方法,会生成类似下面的代码:
1 2 | <input type= "hidden" id= "_wpnonce" name= "_wpnonce" value= "796c7766b1" />
<input type= "hidden" name= "_wp_http_referer" value= "/wp-admin/edit-comments.php" />
|
Salin selepas log masuk
单独生成一个nonce
如果你只是想要生成一个独立的nonce,可以过wp_create_nonce()方法:
1 2 3 | wp_create_nonce( $action );
$nonce = wp_create_nonce( 'my-action_' . $post ->ID );
|
Salin selepas log masuk
同样的,$action为可选参数,默认为-1。上面的方法会返回类似“295a686963”的结果。
验证nonce有效性
验证表单中的nonce
在Admin管理界面,你可以通过check_admin_referer方法来验证Url中Nonce的有效性:
1 | check_admin_referer( $action , $query_arg );
|
Salin selepas log masuk
下面是一个例子演示如何在插件中使用check_admin_referer验证nonce:
1 2 3 4 | <form method= "post" >
<!-- some inputs here -->
<?php wp_nonce_field( 'name_of_my_action', 'name_of_nonce_field' ); ?>
</form>
|
Salin selepas log masuk
验证方法:
1 | check_admin_referer( 'name_of_my_action' , 'name_of_nonce_field' );
|
Salin selepas log masuk
验证Ajax中的nonce
如果要检查Ajax请求中的nonce有效性,可以使用check_ajax_referer()方法:
1 | check_ajax_referer( $action , $query_arg , $die )
|
Salin selepas log masuk
$die指定如果$nonce无效,是否结束脚本执行。(默认为True)
一个简单使用check_ajax_referer的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <?php
$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>
|
Salin selepas log masuk
在向后通过下面的代码进行验证:
1 2 3 4 5 6 | 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();
}
|
Salin selepas log masuk
验证独立生成的nonce
1 2 | 1
wp_verify_nonce( $nonce , $action );
|
Salin selepas log masuk
Atas ialah kandungan terperinci 关于WordPress中的Nonce详解. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!