Nonces

“Nonce”是“Number used ONCE”(一次性使用编码)的缩写。它本质上是一个唯一的十六进制序列号,用于出于安全目的验证请求的来源和意图。顾名思义,每个nonce只能使用一次。

如果你的插件允许用户提交数据,无论是管理端还是公共端,您必须确保该用户就是他们自己,并且他们具有执行操作的必要能力。同时进行这两项操作意味着只有当用户期望数据发生变化时,数据才会发生变化。

 

使用nonce

在我们的检查用户能力示例之后,用户数据提交安全性的下一步是使用nonce。

能力检查确保只有具有删除文章权限的用户才能删除文章,但是如果有人欺骗你点击那个链接呢?你有必要的能力,所以你可能会无意中删除文章。

Nonce可用于检查当前用户是否真的打算执行该动作。

生成删除链接时,您需要使用wp_create_nonce()函数向链接添加nonce,传递给该函数的参数确保所创建的nonce对于该特定操作是唯一的。

然后,当您处理删除链接的请求时,可以检查nonce是否是您所期望的。

关于更多信息,马克·贾奎斯的在WordPress nonces上的文章是一个很好的资源。

译注:以下是我整理自马克·贾奎斯的文章,对理解nonce很有帮助:
Nonce有效期为24小时,在用户请求某页或某个操作时向他们提供一条信息(nonce),执行操作时,将传递并验证该信息。以此确定请求是否来自我们自己的WordPress网站,验证用户的请求是否出自本意。Nonce可以通过多种方式被锁定,它们对于WordPress安装,WordPress用户,操作,操作对象以及操作时间(24小时窗口)都是唯一的。这意味着,如果这些东西中的任何一个发生变化,则随机数是无效的。因此,如果你(以某种方式)拦截了我正在使用的nonce,首先,你只有24小时的时间使用此密钥来试图欺骗我。你只能用这个钥匙在我的博客上欺骗我对特定项目执行一个特定的动作。因此,即使你有一个nonce用来删除一篇文章,最坏的情况是,你也许能够欺骗我删除那个特定的文章。这个nonce对于任何其他目的都是无用的。

 

完整示例

使用能力检查、数据验证、安全输入、安全输出和nonce完成示例:

/**
 * Generate a Delete link based on the homepage url.
 *
 * @param string $content   Existing content.
 *
 * @return string|null
 */
function wporg_generate_delete_link( $content ) {
	// Run only for single post page.
	if ( is_single() && in_the_loop() && is_main_query() ) {
		// Add query arguments: action, post, nonce
		$url = add_query_arg(
			[
				'action' => 'wporg_frontend_delete',
				'post'   => get_the_ID(),
				'nonce'  => wp_create_nonce( 'wporg_frontend_delete' ),
			], home_url()
		);

		return $content . ' <a href="' . esc_url( $url ) . '">' . esc_html__( 'Delete Post', 'wporg' ) . '</a>';
	}

	return null;
}


/**
 * Request handler
 */
function wporg_delete_post() {
	if ( isset( $_GET['action'] )
         && isset( $_GET['nonce'] )
         && 'wporg_frontend_delete' === $_GET['action']
         && wp_verify_nonce( $_GET['nonce'], 'wporg_frontend_delete' ) ) {

		// Verify we have a post id.
		$post_id = ( isset( $_GET['post'] ) ) ? ( $_GET['post'] ) : ( null );

		// Verify there is a post with such a number.
		$post = get_post( (int) $post_id );
		if ( empty( $post ) ) {
			return;
		}

		// Delete the post.
		wp_trash_post( $post_id );

		// Redirect to admin page.
		$redirect = admin_url( 'edit.php' );
		wp_safe_redirect( $redirect );

		// We are done.
		die;
	}
}


/**
 * Add delete post ability
 */
add_action('plugins_loaded', 'wporg_add_delete_post_ability');
 
function wporg_add_delete_post_ability() {    
    if ( current_user_can( 'edit_others_posts' ) ) {
        /**
         * Add the delete link to the end of the post content.
         */
        add_filter( 'the_content', 'wporg_generate_delete_link' );
      
        /**
         * Register our request handler with the init hook.
         */
        add_action( 'init', 'wporg_delete_post' );
    }
}

相关链接:主题开发手册:Nonce 令牌