WordPress未刷新服务器上的nonce令牌

gra*_*vic 5 php wordpress wordpress-plugin custom-wordpress-pages

我的插件中有一个类似于以下内容的表格:

<!-- Client form -->
<form>
   <?php wp_nonce_field('my_form','_my_token'); ?>
   <!-- Additional form fields -->
</form>
Run Code Online (Sandbox Code Playgroud)

它生成这两个字段:

<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" />
Run Code Online (Sandbox Code Playgroud)

提交此表单时,我将按照以下方式进行验证:

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

问题在于,在服务器上,令牌永远不会更改,它始终是相同的,并且在此步骤中验证始终会失败。如果我从WordPress注销,然后再次登录,则客户端令牌已更改,但在服务器上相同。

我已经在本地测试过,当我再次登录时,它总是在两侧更改令牌,但是在我的生产环境中,它仅在客户端更改。

看起来它是以某种方式缓存的,但是不确定到底是什么。我使用过WP Super Cache插件,但是现在已禁用它,并且此问题仍然存在。我在生产站点上启用了多站点功能,但是我认为这与它无关。有任何想法吗?

Ste*_*uel 1

您预计随机数会在什么时间范围内发生变化?

在没有其他更改的连续刷新中,页面加载之间的随机数可能是相同的。基本上,如果您坐在那里并按 F5,您将获得相同的随机数。

这是设计使然。为了使用它们进行验证,需要在短时间内幂等创建随机数。

再说一次,基本上,如果这不能以这种方式工作,你将永远无法验证你的随机数。当您创建它时,该值将是一回事,而当您重新创建它以验证它时,该值将是另一回事。验证总是会失败。

wp_verify_nonce() 可以接受最长 24 小时的随机数(其他条件相同)(请参阅WP Codex 页面)。您可能需要等待更长的时间才能收到不同的随机数。

可能发生的其他系统事件可能会导致生成新的随机数。我从来不需要自己这样做,但看来你可以用来wp_nonce_tick()慢跑这个过程。

有可能其中一个或两者wp_create_nonce()(由 直接使用wp_nonce_field()) 和wp_verify_nonce()可能已被某些插件重写,因为它们都在 中定义pluggable.php并且可用于覆盖。编写良好的 WP 感知 CDN 或其他缓存解决方案可能会做到这一点来持久保存会话。我不知道Super Cache是​​否这样做。

或者,如果您的系统配置尚未这样做,您可以选择自己重写这些函数。这将是安全代码,并且在编写安全代码时要小心:开源安全代码的最大优点是它是经过同行评审的,并且您的(新)代码可能不会相同。